blob: f5eb321928a0d0481c87c61726fc04da143a50fd [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
Antoine Pitroufc8d6f42010-01-17 12:38:54 +00008char _PyByteArray_empty_string[] = "";
Christian Heimes2c9c7a52008-05-26 13:42:13 +00009
10void
11PyByteArray_Fini(void)
12{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000013}
14
15int
16PyByteArray_Init(void)
17{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000018 return 1;
19}
20
21/* end nullbytes support */
22
23/* Helpers */
24
25static int
26_getbytevalue(PyObject* arg, int *value)
27{
28 long face_value;
29
30 if (PyLong_Check(arg)) {
31 face_value = PyLong_AsLong(arg);
Georg Brandl9a54d7c2008-07-16 23:15:30 +000032 } else {
33 PyObject *index = PyNumber_Index(arg);
34 if (index == NULL) {
35 PyErr_Format(PyExc_TypeError, "an integer is required");
Mark Dickinson10de93a2010-07-09 19:25:48 +000036 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000037 return 0;
38 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +000039 face_value = PyLong_AsLong(index);
40 Py_DECREF(index);
41 }
42
43 if (face_value < 0 || face_value >= 256) {
44 /* this includes the OverflowError in case the long is too large */
45 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Mark Dickinson10de93a2010-07-09 19:25:48 +000046 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000047 return 0;
48 }
49
50 *value = face_value;
51 return 1;
52}
53
54static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +000055bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000056{
57 int ret;
58 void *ptr;
59 if (view == NULL) {
60 obj->ob_exports++;
61 return 0;
62 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000063 ptr = (void *) PyByteArray_AS_STRING(obj);
Martin v. Löwis423be952008-08-13 15:53:07 +000064 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
Christian Heimes2c9c7a52008-05-26 13:42:13 +000065 if (ret >= 0) {
66 obj->ob_exports++;
67 }
68 return ret;
69}
70
71static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +000072bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000073{
74 obj->ob_exports--;
75}
76
Antoine Pitrou5504e892008-12-06 21:27:53 +000077static int
78_canresize(PyByteArrayObject *self)
79{
80 if (self->ob_exports > 0) {
81 PyErr_SetString(PyExc_BufferError,
82 "Existing exports of data: object cannot be re-sized");
83 return 0;
84 }
85 return 1;
86}
87
Christian Heimes2c9c7a52008-05-26 13:42:13 +000088/* Direct API functions */
89
90PyObject *
91PyByteArray_FromObject(PyObject *input)
92{
93 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
94 input, NULL);
95}
96
97PyObject *
98PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
99{
100 PyByteArrayObject *new;
101 Py_ssize_t alloc;
102
103 if (size < 0) {
104 PyErr_SetString(PyExc_SystemError,
105 "Negative size passed to PyByteArray_FromStringAndSize");
106 return NULL;
107 }
108
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000109 /* Prevent buffer overflow when setting alloc to size+1. */
110 if (size == PY_SSIZE_T_MAX) {
111 return PyErr_NoMemory();
112 }
113
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000114 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
115 if (new == NULL)
116 return NULL;
117
118 if (size == 0) {
119 new->ob_bytes = NULL;
120 alloc = 0;
121 }
122 else {
123 alloc = size + 1;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100124 new->ob_bytes = PyObject_Malloc(alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000125 if (new->ob_bytes == NULL) {
126 Py_DECREF(new);
127 return PyErr_NoMemory();
128 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +0000129 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000130 memcpy(new->ob_bytes, bytes, size);
131 new->ob_bytes[size] = '\0'; /* Trailing null byte */
132 }
133 Py_SIZE(new) = size;
134 new->ob_alloc = alloc;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200135 new->ob_start = new->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000136 new->ob_exports = 0;
137
138 return (PyObject *)new;
139}
140
141Py_ssize_t
142PyByteArray_Size(PyObject *self)
143{
144 assert(self != NULL);
145 assert(PyByteArray_Check(self));
146
147 return PyByteArray_GET_SIZE(self);
148}
149
150char *
151PyByteArray_AsString(PyObject *self)
152{
153 assert(self != NULL);
154 assert(PyByteArray_Check(self));
155
156 return PyByteArray_AS_STRING(self);
157}
158
159int
Antoine Pitroucc231542014-11-02 18:40:09 +0100160PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000161{
162 void *sval;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200163 PyByteArrayObject *obj = ((PyByteArrayObject *)self);
Antoine Pitroucc231542014-11-02 18:40:09 +0100164 /* All computations are done unsigned to avoid integer overflows
165 (see issue #22335). */
166 size_t alloc = (size_t) obj->ob_alloc;
167 size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
168 size_t size = (size_t) requested_size;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000169
170 assert(self != NULL);
171 assert(PyByteArray_Check(self));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200172 assert(logical_offset <= alloc);
Antoine Pitroucc231542014-11-02 18:40:09 +0100173 assert(requested_size >= 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000174
Antoine Pitroucc231542014-11-02 18:40:09 +0100175 if (requested_size == Py_SIZE(self)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000176 return 0;
177 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200178 if (!_canresize(obj)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000179 return -1;
180 }
181
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200182 if (size + logical_offset + 1 < alloc) {
183 /* Current buffer is large enough to host the requested size,
184 decide on a strategy. */
185 if (size < alloc / 2) {
186 /* Major downsize; resize down to exact size */
187 alloc = size + 1;
188 }
189 else {
190 /* Minor downsize; quick exit */
191 Py_SIZE(self) = size;
192 PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
193 return 0;
194 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000195 }
196 else {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200197 /* Need growing, decide on a strategy */
198 if (size <= alloc * 1.125) {
199 /* Moderate upsize; overallocate similar to list_resize() */
200 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
201 }
202 else {
203 /* Major upsize; resize up to exact size */
204 alloc = size + 1;
205 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000206 }
Antoine Pitroucc231542014-11-02 18:40:09 +0100207 if (alloc > PY_SSIZE_T_MAX) {
208 PyErr_NoMemory();
209 return -1;
210 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000211
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200212 if (logical_offset > 0) {
213 sval = PyObject_Malloc(alloc);
214 if (sval == NULL) {
215 PyErr_NoMemory();
216 return -1;
217 }
Antoine Pitroucc231542014-11-02 18:40:09 +0100218 memcpy(sval, PyByteArray_AS_STRING(self),
219 Py_MIN(requested_size, Py_SIZE(self)));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200220 PyObject_Free(obj->ob_bytes);
221 }
222 else {
223 sval = PyObject_Realloc(obj->ob_bytes, alloc);
224 if (sval == NULL) {
225 PyErr_NoMemory();
226 return -1;
227 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000228 }
229
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200230 obj->ob_bytes = obj->ob_start = sval;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000231 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200232 obj->ob_alloc = alloc;
233 obj->ob_bytes[size] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000234
235 return 0;
236}
237
238PyObject *
239PyByteArray_Concat(PyObject *a, PyObject *b)
240{
241 Py_ssize_t size;
242 Py_buffer va, vb;
243 PyByteArrayObject *result = NULL;
244
245 va.len = -1;
246 vb.len = -1;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200247 if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
248 PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000249 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
250 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
251 goto done;
252 }
253
254 size = va.len + vb.len;
255 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000256 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000257 goto done;
258 }
259
260 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
261 if (result != NULL) {
262 memcpy(result->ob_bytes, va.buf, va.len);
263 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
264 }
265
266 done:
267 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000268 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000269 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000270 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000271 return (PyObject *)result;
272}
273
274/* Functions stuffed into the type object */
275
276static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000277bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000278{
279 return Py_SIZE(self);
280}
281
282static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000283bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000284{
285 Py_ssize_t mysize;
286 Py_ssize_t size;
287 Py_buffer vo;
288
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200289 if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000290 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
291 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
292 return NULL;
293 }
294
295 mysize = Py_SIZE(self);
296 size = mysize + vo.len;
297 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000298 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000299 return PyErr_NoMemory();
300 }
301 if (size < self->ob_alloc) {
302 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200303 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000304 }
305 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000306 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000307 return NULL;
308 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200309 memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000310 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000311 Py_INCREF(self);
312 return (PyObject *)self;
313}
314
315static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000316bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000317{
318 PyByteArrayObject *result;
319 Py_ssize_t mysize;
320 Py_ssize_t size;
321
322 if (count < 0)
323 count = 0;
324 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000325 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000326 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000327 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000328 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
329 if (result != NULL && size != 0) {
330 if (mysize == 1)
331 memset(result->ob_bytes, self->ob_bytes[0], size);
332 else {
333 Py_ssize_t i;
334 for (i = 0; i < count; i++)
335 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
336 }
337 }
338 return (PyObject *)result;
339}
340
341static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000342bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000343{
344 Py_ssize_t mysize;
345 Py_ssize_t size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200346 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000347
348 if (count < 0)
349 count = 0;
350 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000351 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000352 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000353 size = mysize * count;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200354 if (PyByteArray_Resize((PyObject *)self, size) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000355 return NULL;
356
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200357 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000358 if (mysize == 1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200359 memset(buf, buf[0], size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000360 else {
361 Py_ssize_t i;
362 for (i = 1; i < count; i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200363 memcpy(buf + i*mysize, buf, mysize);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000364 }
365
366 Py_INCREF(self);
367 return (PyObject *)self;
368}
369
370static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000371bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000372{
373 if (i < 0)
374 i += Py_SIZE(self);
375 if (i < 0 || i >= Py_SIZE(self)) {
376 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
377 return NULL;
378 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200379 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000380}
381
382static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000383bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000384{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000385 if (PyIndex_Check(index)) {
386 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000387
388 if (i == -1 && PyErr_Occurred())
389 return NULL;
390
391 if (i < 0)
392 i += PyByteArray_GET_SIZE(self);
393
394 if (i < 0 || i >= Py_SIZE(self)) {
395 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
396 return NULL;
397 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200398 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000399 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000400 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000401 Py_ssize_t start, stop, step, slicelength, cur, i;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000402 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000403 PyByteArray_GET_SIZE(self),
404 &start, &stop, &step, &slicelength) < 0) {
405 return NULL;
406 }
407
408 if (slicelength <= 0)
409 return PyByteArray_FromStringAndSize("", 0);
410 else if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200411 return PyByteArray_FromStringAndSize(
412 PyByteArray_AS_STRING(self) + start, slicelength);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000413 }
414 else {
415 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000416 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000417 PyObject *result;
418
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000419 result = PyByteArray_FromStringAndSize(NULL, slicelength);
420 if (result == NULL)
421 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000422
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000423 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000424 for (cur = start, i = 0; i < slicelength;
425 cur += step, i++) {
426 result_buf[i] = source_buf[cur];
427 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000428 return result;
429 }
430 }
431 else {
432 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
433 return NULL;
434 }
435}
436
437static int
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200438bytearray_setslice_linear(PyByteArrayObject *self,
439 Py_ssize_t lo, Py_ssize_t hi,
440 char *bytes, Py_ssize_t bytes_len)
441{
442 Py_ssize_t avail = hi - lo;
443 char *buf = PyByteArray_AS_STRING(self);
444 Py_ssize_t growth = bytes_len - avail;
Victor Stinner84557232013-11-21 12:29:51 +0100445 int res = 0;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200446 assert(avail >= 0);
447
Victor Stinner84557232013-11-21 12:29:51 +0100448 if (growth < 0) {
449 if (!_canresize(self))
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200450 return -1;
Victor Stinner84557232013-11-21 12:29:51 +0100451
452 if (lo == 0) {
453 /* Shrink the buffer by advancing its logical start */
454 self->ob_start -= growth;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200455 /*
Victor Stinner84557232013-11-21 12:29:51 +0100456 0 lo hi old_size
457 | |<----avail----->|<-----tail------>|
458 | |<-bytes_len->|<-----tail------>|
459 0 new_lo new_hi new_size
460 */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200461 }
Victor Stinner84557232013-11-21 12:29:51 +0100462 else {
463 /*
464 0 lo hi old_size
465 | |<----avail----->|<-----tomove------>|
466 | |<-bytes_len->|<-----tomove------>|
467 0 lo new_hi new_size
468 */
469 memmove(buf + lo + bytes_len, buf + hi,
470 Py_SIZE(self) - hi);
471 }
472 if (PyByteArray_Resize((PyObject *)self,
473 Py_SIZE(self) + growth) < 0) {
474 /* Issue #19578: Handling the memory allocation failure here is
475 tricky here because the bytearray object has already been
476 modified. Depending on growth and lo, the behaviour is
477 different.
478
479 If growth < 0 and lo != 0, the operation is completed, but a
480 MemoryError is still raised and the memory block is not
481 shrinked. Otherwise, the bytearray is restored in its previous
482 state and a MemoryError is raised. */
483 if (lo == 0) {
484 self->ob_start += growth;
485 return -1;
486 }
487 /* memmove() removed bytes, the bytearray object cannot be
488 restored in its previous state. */
489 Py_SIZE(self) += growth;
490 res = -1;
491 }
492 buf = PyByteArray_AS_STRING(self);
493 }
494 else if (growth > 0) {
495 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
496 PyErr_NoMemory();
497 return -1;
498 }
499
500 if (PyByteArray_Resize((PyObject *)self,
501 Py_SIZE(self) + growth) < 0) {
502 return -1;
503 }
504 buf = PyByteArray_AS_STRING(self);
505 /* Make the place for the additional bytes */
506 /*
507 0 lo hi old_size
508 | |<-avail->|<-----tomove------>|
509 | |<---bytes_len-->|<-----tomove------>|
510 0 lo new_hi new_size
511 */
512 memmove(buf + lo + bytes_len, buf + hi,
513 Py_SIZE(self) - lo - bytes_len);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200514 }
515
516 if (bytes_len > 0)
517 memcpy(buf + lo, bytes, bytes_len);
Victor Stinner84557232013-11-21 12:29:51 +0100518 return res;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200519}
520
521static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000522bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000523 PyObject *values)
524{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200525 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000526 void *bytes;
527 Py_buffer vbytes;
528 int res = 0;
529
530 vbytes.len = -1;
531 if (values == (PyObject *)self) {
532 /* Make a copy and call this function recursively */
533 int err;
534 values = PyByteArray_FromObject(values);
535 if (values == NULL)
536 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000537 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000538 Py_DECREF(values);
539 return err;
540 }
541 if (values == NULL) {
542 /* del b[lo:hi] */
543 bytes = NULL;
544 needed = 0;
545 }
546 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200547 if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
548 PyErr_Format(PyExc_TypeError,
549 "can't set bytearray slice from %.100s",
550 Py_TYPE(values)->tp_name);
551 return -1;
552 }
553 needed = vbytes.len;
554 bytes = vbytes.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000555 }
556
557 if (lo < 0)
558 lo = 0;
559 if (hi < lo)
560 hi = lo;
561 if (hi > Py_SIZE(self))
562 hi = Py_SIZE(self);
563
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200564 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000565 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200566 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000567 return res;
568}
569
570static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000571bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000572{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000573 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000574
575 if (i < 0)
576 i += Py_SIZE(self);
577
578 if (i < 0 || i >= Py_SIZE(self)) {
579 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
580 return -1;
581 }
582
583 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000584 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000585
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000586 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000587 return -1;
588
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200589 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000590 return 0;
591}
592
593static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000594bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000595{
596 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200597 char *buf, *bytes;
598 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000599
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000600 if (PyIndex_Check(index)) {
601 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000602
603 if (i == -1 && PyErr_Occurred())
604 return -1;
605
606 if (i < 0)
607 i += PyByteArray_GET_SIZE(self);
608
609 if (i < 0 || i >= Py_SIZE(self)) {
610 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
611 return -1;
612 }
613
614 if (values == NULL) {
615 /* Fall through to slice assignment */
616 start = i;
617 stop = i + 1;
618 step = 1;
619 slicelen = 1;
620 }
621 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000622 int ival;
623 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000624 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200625 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000626 return 0;
627 }
628 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000629 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000630 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000631 PyByteArray_GET_SIZE(self),
632 &start, &stop, &step, &slicelen) < 0) {
633 return -1;
634 }
635 }
636 else {
637 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
638 return -1;
639 }
640
641 if (values == NULL) {
642 bytes = NULL;
643 needed = 0;
644 }
645 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100646 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200647 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
648 PyErr_SetString(PyExc_TypeError,
649 "can assign only bytes, buffers, or iterables "
650 "of ints in range(0, 256)");
651 return -1;
652 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000653 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000654 values = PyByteArray_FromObject(values);
655 if (values == NULL)
656 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000657 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000658 Py_DECREF(values);
659 return err;
660 }
661 else {
662 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200663 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000664 needed = Py_SIZE(values);
665 }
666 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
667 if ((step < 0 && start < stop) ||
668 (step > 0 && start > stop))
669 stop = start;
670 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200671 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000672 }
673 else {
674 if (needed == 0) {
675 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000676 size_t cur;
677 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000678
Antoine Pitrou5504e892008-12-06 21:27:53 +0000679 if (!_canresize(self))
680 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000681
682 if (slicelen == 0)
683 /* Nothing to do here. */
684 return 0;
685
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000686 if (step < 0) {
687 stop = start + 1;
688 start = stop + step * (slicelen - 1) - 1;
689 step = -step;
690 }
691 for (cur = start, i = 0;
692 i < slicelen; cur += step, i++) {
693 Py_ssize_t lim = step - 1;
694
Mark Dickinson66f575b2010-02-14 12:53:32 +0000695 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000696 lim = PyByteArray_GET_SIZE(self) - cur - 1;
697
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200698 memmove(buf + cur - i,
699 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000700 }
701 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000702 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000703 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200704 memmove(buf + cur - slicelen,
705 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000706 PyByteArray_GET_SIZE(self) - cur);
707 }
708 if (PyByteArray_Resize((PyObject *)self,
709 PyByteArray_GET_SIZE(self) - slicelen) < 0)
710 return -1;
711
712 return 0;
713 }
714 else {
715 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000716 Py_ssize_t i;
717 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000718
719 if (needed != slicelen) {
720 PyErr_Format(PyExc_ValueError,
721 "attempt to assign bytes of size %zd "
722 "to extended slice of size %zd",
723 needed, slicelen);
724 return -1;
725 }
726 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200727 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000728 return 0;
729 }
730 }
731}
732
733static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000734bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000735{
736 static char *kwlist[] = {"source", "encoding", "errors", 0};
737 PyObject *arg = NULL;
738 const char *encoding = NULL;
739 const char *errors = NULL;
740 Py_ssize_t count;
741 PyObject *it;
742 PyObject *(*iternext)(PyObject *);
743
744 if (Py_SIZE(self) != 0) {
745 /* Empty previous contents (yes, do this first of all!) */
746 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
747 return -1;
748 }
749
750 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000751 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000752 &arg, &encoding, &errors))
753 return -1;
754
755 /* Make a quick exit if no first argument */
756 if (arg == NULL) {
757 if (encoding != NULL || errors != NULL) {
758 PyErr_SetString(PyExc_TypeError,
759 "encoding or errors without sequence argument");
760 return -1;
761 }
762 return 0;
763 }
764
765 if (PyUnicode_Check(arg)) {
766 /* Encode via the codec registry */
767 PyObject *encoded, *new;
768 if (encoding == NULL) {
769 PyErr_SetString(PyExc_TypeError,
770 "string argument without an encoding");
771 return -1;
772 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000773 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000774 if (encoded == NULL)
775 return -1;
776 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000777 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000778 Py_DECREF(encoded);
779 if (new == NULL)
780 return -1;
781 Py_DECREF(new);
782 return 0;
783 }
784
785 /* If it's not unicode, there can't be encoding or errors */
786 if (encoding != NULL || errors != NULL) {
787 PyErr_SetString(PyExc_TypeError,
788 "encoding or errors without a string argument");
789 return -1;
790 }
791
792 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000793 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
794 if (count == -1 && PyErr_Occurred()) {
795 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000796 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000797 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000798 }
799 else if (count < 0) {
800 PyErr_SetString(PyExc_ValueError, "negative count");
801 return -1;
802 }
803 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000804 if (count > 0) {
805 if (PyByteArray_Resize((PyObject *)self, count))
806 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200807 memset(PyByteArray_AS_STRING(self), 0, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000808 }
809 return 0;
810 }
811
812 /* Use the buffer API */
813 if (PyObject_CheckBuffer(arg)) {
814 Py_ssize_t size;
815 Py_buffer view;
816 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
817 return -1;
818 size = view.len;
819 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200820 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
821 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200822 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000823 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000824 return 0;
825 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000826 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000827 return -1;
828 }
829
830 /* XXX Optimize this if the arguments is a list, tuple */
831
832 /* Get the iterator */
833 it = PyObject_GetIter(arg);
834 if (it == NULL)
835 return -1;
836 iternext = *Py_TYPE(it)->tp_iternext;
837
838 /* Run the iterator to exhaustion */
839 for (;;) {
840 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000841 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000842
843 /* Get the next item */
844 item = iternext(it);
845 if (item == NULL) {
846 if (PyErr_Occurred()) {
847 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
848 goto error;
849 PyErr_Clear();
850 }
851 break;
852 }
853
854 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000855 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000856 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000857 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000858 goto error;
859
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000860 /* Append the byte */
861 if (Py_SIZE(self) < self->ob_alloc)
862 Py_SIZE(self)++;
863 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
864 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200865 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000866 }
867
868 /* Clean up and return success */
869 Py_DECREF(it);
870 return 0;
871
872 error:
873 /* Error handling when it != NULL */
874 Py_DECREF(it);
875 return -1;
876}
877
878/* Mostly copied from string_repr, but without the
879 "smart quote" functionality. */
880static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000881bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000882{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000883 const char *quote_prefix = "bytearray(b";
884 const char *quote_postfix = ")";
885 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200886 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000887 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000888 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200889 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200890 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200891 char c;
892 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200893 int quote;
894 char *test, *start;
895 char *buffer;
896
897 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000898 PyErr_SetString(PyExc_OverflowError,
899 "bytearray object is too large to make repr");
900 return NULL;
901 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200902
903 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100904 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200905 if (buffer == NULL) {
906 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000907 return NULL;
908 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000909
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200910 /* Figure out which quote to use; single is preferred */
911 quote = '\'';
912 start = PyByteArray_AS_STRING(self);
913 for (test = start; test < start+length; ++test) {
914 if (*test == '"') {
915 quote = '\''; /* back to single */
916 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000917 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200918 else if (*test == '\'')
919 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000920 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200921
922 p = buffer;
923 while (*quote_prefix)
924 *p++ = *quote_prefix++;
925 *p++ = quote;
926
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200927 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200928 for (i = 0; i < length; i++) {
929 /* There's at least enough room for a hex escape
930 and a closing quote. */
931 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200932 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200933 if (c == '\'' || c == '\\')
934 *p++ = '\\', *p++ = c;
935 else if (c == '\t')
936 *p++ = '\\', *p++ = 't';
937 else if (c == '\n')
938 *p++ = '\\', *p++ = 'n';
939 else if (c == '\r')
940 *p++ = '\\', *p++ = 'r';
941 else if (c == 0)
942 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
943 else if (c < ' ' || c >= 0x7f) {
944 *p++ = '\\';
945 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200946 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
947 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200948 }
949 else
950 *p++ = c;
951 }
952 assert(newsize - (p - buffer) >= 1);
953 *p++ = quote;
954 while (*quote_postfix) {
955 *p++ = *quote_postfix++;
956 }
957
958 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100959 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200960 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000961}
962
963static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000964bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000965{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000966 if (Py_BytesWarningFlag) {
967 if (PyErr_WarnEx(PyExc_BytesWarning,
968 "str() on a bytearray instance", 1))
969 return NULL;
970 }
971 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000972}
973
974static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000975bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000976{
977 Py_ssize_t self_size, other_size;
978 Py_buffer self_bytes, other_bytes;
979 PyObject *res;
980 Py_ssize_t minsize;
981 int cmp;
982
983 /* Bytes can be compared to anything that supports the (binary)
984 buffer API. Except that a comparison with Unicode is always an
985 error, even if the comparison is for equality. */
986 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
987 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000988 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000989 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000990 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000991 return NULL;
992 }
993
Brian Curtindfc80e32011-08-10 20:28:54 -0500994 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000995 }
996
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200997 if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000998 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -0500999 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001000 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001001 self_size = self_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001002
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001003 if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001004 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001005 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001006 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001007 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001008 other_size = other_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001009
1010 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1011 /* Shortcut: if the lengths differ, the objects differ */
1012 cmp = (op == Py_NE);
1013 }
1014 else {
1015 minsize = self_size;
1016 if (other_size < minsize)
1017 minsize = other_size;
1018
1019 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1020 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1021
1022 if (cmp == 0) {
1023 if (self_size < other_size)
1024 cmp = -1;
1025 else if (self_size > other_size)
1026 cmp = 1;
1027 }
1028
1029 switch (op) {
1030 case Py_LT: cmp = cmp < 0; break;
1031 case Py_LE: cmp = cmp <= 0; break;
1032 case Py_EQ: cmp = cmp == 0; break;
1033 case Py_NE: cmp = cmp != 0; break;
1034 case Py_GT: cmp = cmp > 0; break;
1035 case Py_GE: cmp = cmp >= 0; break;
1036 }
1037 }
1038
1039 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001040 PyBuffer_Release(&self_bytes);
1041 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001042 Py_INCREF(res);
1043 return res;
1044}
1045
1046static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001047bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001048{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001049 if (self->ob_exports > 0) {
1050 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001051 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001052 PyErr_Print();
1053 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001054 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001055 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001056 }
1057 Py_TYPE(self)->tp_free((PyObject *)self);
1058}
1059
1060
1061/* -------------------------------------------------------------------- */
1062/* Methods */
1063
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001064#define FASTSEARCH fastsearch
1065#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001066#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001067#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001068#define STRINGLIB_LEN PyByteArray_GET_SIZE
1069#define STRINGLIB_STR PyByteArray_AS_STRING
1070#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001071#define STRINGLIB_ISSPACE Py_ISSPACE
1072#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001073#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1074#define STRINGLIB_MUTABLE 1
1075
1076#include "stringlib/fastsearch.h"
1077#include "stringlib/count.h"
1078#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001079#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001080#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001081#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001082#include "stringlib/ctype.h"
1083#include "stringlib/transmogrify.h"
1084
1085
1086/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1087were copied from the old char* style string object. */
1088
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001089/* helper macro to fixup start/end slice values */
1090#define ADJUST_INDICES(start, end, len) \
1091 if (end > len) \
1092 end = len; \
1093 else if (end < 0) { \
1094 end += len; \
1095 if (end < 0) \
1096 end = 0; \
1097 } \
1098 if (start < 0) { \
1099 start += len; \
1100 if (start < 0) \
1101 start = 0; \
1102 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001103
1104Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001105bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001106{
1107 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001108 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001109 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001110 const char *sub;
1111 Py_ssize_t sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001112 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1113 Py_ssize_t res;
1114
Antoine Pitrouac65d962011-10-20 23:54:17 +02001115 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1116 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001117 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001118
1119 if (subobj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001120 if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001121 return -2;
1122
1123 sub = subbuf.buf;
1124 sub_len = subbuf.len;
1125 }
1126 else {
1127 sub = &byte;
1128 sub_len = 1;
1129 }
1130
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001131 if (dir > 0)
1132 res = stringlib_find_slice(
1133 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001134 sub, sub_len, start, end);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001135 else
1136 res = stringlib_rfind_slice(
1137 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001138 sub, sub_len, start, end);
1139
1140 if (subobj)
1141 PyBuffer_Release(&subbuf);
1142
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001143 return res;
1144}
1145
1146PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001147"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001148\n\
1149Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001150such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001151arguments start and end are interpreted as in slice notation.\n\
1152\n\
1153Return -1 on failure.");
1154
1155static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001156bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001157{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001158 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001159 if (result == -2)
1160 return NULL;
1161 return PyLong_FromSsize_t(result);
1162}
1163
1164PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001165"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001166\n\
1167Return the number of non-overlapping occurrences of subsection sub in\n\
1168bytes B[start:end]. Optional arguments start and end are interpreted\n\
1169as in slice notation.");
1170
1171static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001172bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001173{
1174 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001175 const char *str = PyByteArray_AS_STRING(self), *sub;
1176 Py_ssize_t sub_len;
1177 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001178 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001179
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001180 Py_buffer vsub;
1181 PyObject *count_obj;
1182
Antoine Pitrouac65d962011-10-20 23:54:17 +02001183 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1184 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001185 return NULL;
1186
Antoine Pitrouac65d962011-10-20 23:54:17 +02001187 if (sub_obj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001188 if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001189 return NULL;
1190
1191 sub = vsub.buf;
1192 sub_len = vsub.len;
1193 }
1194 else {
1195 sub = &byte;
1196 sub_len = 1;
1197 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001198
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001199 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001200
1201 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001202 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001203 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001204
1205 if (sub_obj)
1206 PyBuffer_Release(&vsub);
1207
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001208 return count_obj;
1209}
1210
Eli Bendersky4db28d32011-03-03 18:21:02 +00001211PyDoc_STRVAR(clear__doc__,
1212"B.clear() -> None\n\
1213\n\
1214Remove all items from B.");
1215
Victor Stinner6430fd52011-09-29 04:02:13 +02001216static PyObject *
Eli Bendersky4db28d32011-03-03 18:21:02 +00001217bytearray_clear(PyByteArrayObject *self)
1218{
1219 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1220 return NULL;
1221 Py_RETURN_NONE;
1222}
1223
1224PyDoc_STRVAR(copy__doc__,
1225"B.copy() -> bytearray\n\
1226\n\
1227Return a copy of B.");
1228
1229static PyObject *
1230bytearray_copy(PyByteArrayObject *self)
1231{
1232 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1233 PyByteArray_GET_SIZE(self));
1234}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001235
1236PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001237"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001238\n\
1239Like B.find() but raise ValueError when the subsection is not found.");
1240
1241static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001242bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001243{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001244 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001245 if (result == -2)
1246 return NULL;
1247 if (result == -1) {
1248 PyErr_SetString(PyExc_ValueError,
1249 "subsection not found");
1250 return NULL;
1251 }
1252 return PyLong_FromSsize_t(result);
1253}
1254
1255
1256PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001257"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001258\n\
1259Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001260such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001261arguments start and end are interpreted as in slice notation.\n\
1262\n\
1263Return -1 on failure.");
1264
1265static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001266bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001267{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001268 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001269 if (result == -2)
1270 return NULL;
1271 return PyLong_FromSsize_t(result);
1272}
1273
1274
1275PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001276"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001277\n\
1278Like B.rfind() but raise ValueError when the subsection is not found.");
1279
1280static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001281bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001282{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001283 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001284 if (result == -2)
1285 return NULL;
1286 if (result == -1) {
1287 PyErr_SetString(PyExc_ValueError,
1288 "subsection not found");
1289 return NULL;
1290 }
1291 return PyLong_FromSsize_t(result);
1292}
1293
1294
1295static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001296bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001297{
1298 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1299 if (ival == -1 && PyErr_Occurred()) {
1300 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001301 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001302 PyErr_Clear();
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001303 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001304 return -1;
1305 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1306 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001307 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001308 return pos >= 0;
1309 }
1310 if (ival < 0 || ival >= 256) {
1311 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1312 return -1;
1313 }
1314
Antoine Pitrou0010d372010-08-15 17:12:55 +00001315 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001316}
1317
1318
1319/* Matches the end (direction >= 0) or start (direction < 0) of self
1320 * against substr, using the start and end arguments. Returns
1321 * -1 on error, 0 if not found and 1 if found.
1322 */
1323Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001324_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001325 Py_ssize_t end, int direction)
1326{
1327 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1328 const char* str;
1329 Py_buffer vsubstr;
1330 int rv = 0;
1331
1332 str = PyByteArray_AS_STRING(self);
1333
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001334 if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001335 return -1;
1336
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001337 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001338
1339 if (direction < 0) {
1340 /* startswith */
1341 if (start+vsubstr.len > len) {
1342 goto done;
1343 }
1344 } else {
1345 /* endswith */
1346 if (end-start < vsubstr.len || start > len) {
1347 goto done;
1348 }
1349
1350 if (end-vsubstr.len > start)
1351 start = end - vsubstr.len;
1352 }
1353 if (end-start >= vsubstr.len)
1354 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1355
1356done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001357 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001358 return rv;
1359}
1360
1361
1362PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001363"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001364\n\
1365Return True if B starts with the specified prefix, False otherwise.\n\
1366With optional start, test B beginning at that position.\n\
1367With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001368prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001369
1370static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001371bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001372{
1373 Py_ssize_t start = 0;
1374 Py_ssize_t end = PY_SSIZE_T_MAX;
1375 PyObject *subobj;
1376 int result;
1377
Jesus Ceaac451502011-04-20 17:09:23 +02001378 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001379 return NULL;
1380 if (PyTuple_Check(subobj)) {
1381 Py_ssize_t i;
1382 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001383 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001384 PyTuple_GET_ITEM(subobj, i),
1385 start, end, -1);
1386 if (result == -1)
1387 return NULL;
1388 else if (result) {
1389 Py_RETURN_TRUE;
1390 }
1391 }
1392 Py_RETURN_FALSE;
1393 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001394 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001395 if (result == -1) {
1396 if (PyErr_ExceptionMatches(PyExc_TypeError))
1397 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1398 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001399 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001400 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001401 else
1402 return PyBool_FromLong(result);
1403}
1404
1405PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001406"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001407\n\
1408Return True if B ends with the specified suffix, False otherwise.\n\
1409With optional start, test B beginning at that position.\n\
1410With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001411suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001412
1413static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001414bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001415{
1416 Py_ssize_t start = 0;
1417 Py_ssize_t end = PY_SSIZE_T_MAX;
1418 PyObject *subobj;
1419 int result;
1420
Jesus Ceaac451502011-04-20 17:09:23 +02001421 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001422 return NULL;
1423 if (PyTuple_Check(subobj)) {
1424 Py_ssize_t i;
1425 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001426 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001427 PyTuple_GET_ITEM(subobj, i),
1428 start, end, +1);
1429 if (result == -1)
1430 return NULL;
1431 else if (result) {
1432 Py_RETURN_TRUE;
1433 }
1434 }
1435 Py_RETURN_FALSE;
1436 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001437 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001438 if (result == -1) {
1439 if (PyErr_ExceptionMatches(PyExc_TypeError))
1440 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1441 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001442 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001443 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001444 else
1445 return PyBool_FromLong(result);
1446}
1447
1448
1449PyDoc_STRVAR(translate__doc__,
1450"B.translate(table[, deletechars]) -> bytearray\n\
1451\n\
1452Return a copy of B, where all characters occurring in the\n\
1453optional argument deletechars are removed, and the remaining\n\
1454characters have been mapped through the given translation\n\
1455table, which must be a bytes object of length 256.");
1456
1457static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001458bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001459{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001460 char *input, *output;
1461 const char *table;
1462 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001463 PyObject *input_obj = (PyObject*)self;
1464 const char *output_start;
1465 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001466 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001467 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001468 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001469 Py_buffer vtable, vdel;
1470
1471 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1472 &tableobj, &delobj))
1473 return NULL;
1474
Georg Brandlccc47b62008-12-28 11:44:14 +00001475 if (tableobj == Py_None) {
1476 table = NULL;
1477 tableobj = NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001478 } else if (PyObject_GetBuffer(tableobj, &vtable, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001479 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001480 } else {
1481 if (vtable.len != 256) {
1482 PyErr_SetString(PyExc_ValueError,
1483 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001484 PyBuffer_Release(&vtable);
1485 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001486 }
1487 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001488 }
1489
1490 if (delobj != NULL) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001491 if (PyObject_GetBuffer(delobj, &vdel, PyBUF_SIMPLE) != 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001492 if (tableobj != NULL)
1493 PyBuffer_Release(&vtable);
1494 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001495 }
1496 }
1497 else {
1498 vdel.buf = NULL;
1499 vdel.len = 0;
1500 }
1501
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001502 inlen = PyByteArray_GET_SIZE(input_obj);
1503 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1504 if (result == NULL)
1505 goto done;
1506 output_start = output = PyByteArray_AsString(result);
1507 input = PyByteArray_AS_STRING(input_obj);
1508
Georg Brandlccc47b62008-12-28 11:44:14 +00001509 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001510 /* If no deletions are required, use faster code */
1511 for (i = inlen; --i >= 0; ) {
1512 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001513 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001514 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001515 goto done;
1516 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001517
1518 if (table == NULL) {
1519 for (i = 0; i < 256; i++)
1520 trans_table[i] = Py_CHARMASK(i);
1521 } else {
1522 for (i = 0; i < 256; i++)
1523 trans_table[i] = Py_CHARMASK(table[i]);
1524 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001525
1526 for (i = 0; i < vdel.len; i++)
1527 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1528
1529 for (i = inlen; --i >= 0; ) {
1530 c = Py_CHARMASK(*input++);
1531 if (trans_table[c] != -1)
1532 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1533 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001534 }
1535 /* Fix the size of the resulting string */
1536 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001537 if (PyByteArray_Resize(result, output - output_start) < 0) {
1538 Py_CLEAR(result);
1539 goto done;
1540 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001541
1542done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001543 if (tableobj != NULL)
1544 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001545 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001546 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001547 return result;
1548}
1549
1550
Georg Brandlabc38772009-04-12 15:51:51 +00001551static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001552bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001553{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001554 return _Py_bytes_maketrans(args);
Georg Brandlabc38772009-04-12 15:51:51 +00001555}
1556
1557
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001558/* find and count characters and substrings */
1559
1560#define findchar(target, target_len, c) \
1561 ((char *)memchr((const void *)(target), c, target_len))
1562
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001563
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001564/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001565Py_LOCAL(PyByteArrayObject *)
1566return_self(PyByteArrayObject *self)
1567{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001568 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001569 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1570 PyByteArray_AS_STRING(self),
1571 PyByteArray_GET_SIZE(self));
1572}
1573
1574Py_LOCAL_INLINE(Py_ssize_t)
1575countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1576{
1577 Py_ssize_t count=0;
1578 const char *start=target;
1579 const char *end=target+target_len;
1580
1581 while ( (start=findchar(start, end-start, c)) != NULL ) {
1582 count++;
1583 if (count >= maxcount)
1584 break;
1585 start += 1;
1586 }
1587 return count;
1588}
1589
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001590
1591/* Algorithms for different cases of string replacement */
1592
1593/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1594Py_LOCAL(PyByteArrayObject *)
1595replace_interleave(PyByteArrayObject *self,
1596 const char *to_s, Py_ssize_t to_len,
1597 Py_ssize_t maxcount)
1598{
1599 char *self_s, *result_s;
1600 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001601 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001602 PyByteArrayObject *result;
1603
1604 self_len = PyByteArray_GET_SIZE(self);
1605
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001606 /* 1 at the end plus 1 after every character;
1607 count = min(maxcount, self_len + 1) */
1608 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001609 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001610 else
1611 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1612 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001613
1614 /* Check for overflow */
1615 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001616 assert(count > 0);
1617 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001618 PyErr_SetString(PyExc_OverflowError,
1619 "replace string is too long");
1620 return NULL;
1621 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001622 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001623
1624 if (! (result = (PyByteArrayObject *)
1625 PyByteArray_FromStringAndSize(NULL, result_len)) )
1626 return NULL;
1627
1628 self_s = PyByteArray_AS_STRING(self);
1629 result_s = PyByteArray_AS_STRING(result);
1630
1631 /* TODO: special case single character, which doesn't need memcpy */
1632
1633 /* Lay the first one down (guaranteed this will occur) */
1634 Py_MEMCPY(result_s, to_s, to_len);
1635 result_s += to_len;
1636 count -= 1;
1637
1638 for (i=0; i<count; i++) {
1639 *result_s++ = *self_s++;
1640 Py_MEMCPY(result_s, to_s, to_len);
1641 result_s += to_len;
1642 }
1643
1644 /* Copy the rest of the original string */
1645 Py_MEMCPY(result_s, self_s, self_len-i);
1646
1647 return result;
1648}
1649
1650/* Special case for deleting a single character */
1651/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1652Py_LOCAL(PyByteArrayObject *)
1653replace_delete_single_character(PyByteArrayObject *self,
1654 char from_c, Py_ssize_t maxcount)
1655{
1656 char *self_s, *result_s;
1657 char *start, *next, *end;
1658 Py_ssize_t self_len, result_len;
1659 Py_ssize_t count;
1660 PyByteArrayObject *result;
1661
1662 self_len = PyByteArray_GET_SIZE(self);
1663 self_s = PyByteArray_AS_STRING(self);
1664
1665 count = countchar(self_s, self_len, from_c, maxcount);
1666 if (count == 0) {
1667 return return_self(self);
1668 }
1669
1670 result_len = self_len - count; /* from_len == 1 */
1671 assert(result_len>=0);
1672
1673 if ( (result = (PyByteArrayObject *)
1674 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1675 return NULL;
1676 result_s = PyByteArray_AS_STRING(result);
1677
1678 start = self_s;
1679 end = self_s + self_len;
1680 while (count-- > 0) {
1681 next = findchar(start, end-start, from_c);
1682 if (next == NULL)
1683 break;
1684 Py_MEMCPY(result_s, start, next-start);
1685 result_s += (next-start);
1686 start = next+1;
1687 }
1688 Py_MEMCPY(result_s, start, end-start);
1689
1690 return result;
1691}
1692
1693/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1694
1695Py_LOCAL(PyByteArrayObject *)
1696replace_delete_substring(PyByteArrayObject *self,
1697 const char *from_s, Py_ssize_t from_len,
1698 Py_ssize_t maxcount)
1699{
1700 char *self_s, *result_s;
1701 char *start, *next, *end;
1702 Py_ssize_t self_len, result_len;
1703 Py_ssize_t count, offset;
1704 PyByteArrayObject *result;
1705
1706 self_len = PyByteArray_GET_SIZE(self);
1707 self_s = PyByteArray_AS_STRING(self);
1708
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001709 count = stringlib_count(self_s, self_len,
1710 from_s, from_len,
1711 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001712
1713 if (count == 0) {
1714 /* no matches */
1715 return return_self(self);
1716 }
1717
1718 result_len = self_len - (count * from_len);
1719 assert (result_len>=0);
1720
1721 if ( (result = (PyByteArrayObject *)
1722 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1723 return NULL;
1724
1725 result_s = PyByteArray_AS_STRING(result);
1726
1727 start = self_s;
1728 end = self_s + self_len;
1729 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001730 offset = stringlib_find(start, end-start,
1731 from_s, from_len,
1732 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001733 if (offset == -1)
1734 break;
1735 next = start + offset;
1736
1737 Py_MEMCPY(result_s, start, next-start);
1738
1739 result_s += (next-start);
1740 start = next+from_len;
1741 }
1742 Py_MEMCPY(result_s, start, end-start);
1743 return result;
1744}
1745
1746/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1747Py_LOCAL(PyByteArrayObject *)
1748replace_single_character_in_place(PyByteArrayObject *self,
1749 char from_c, char to_c,
1750 Py_ssize_t maxcount)
1751{
Antoine Pitroud1188562010-06-09 16:38:55 +00001752 char *self_s, *result_s, *start, *end, *next;
1753 Py_ssize_t self_len;
1754 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001755
Antoine Pitroud1188562010-06-09 16:38:55 +00001756 /* The result string will be the same size */
1757 self_s = PyByteArray_AS_STRING(self);
1758 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001759
Antoine Pitroud1188562010-06-09 16:38:55 +00001760 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001761
Antoine Pitroud1188562010-06-09 16:38:55 +00001762 if (next == NULL) {
1763 /* No matches; return the original bytes */
1764 return return_self(self);
1765 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001766
Antoine Pitroud1188562010-06-09 16:38:55 +00001767 /* Need to make a new bytes */
1768 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1769 if (result == NULL)
1770 return NULL;
1771 result_s = PyByteArray_AS_STRING(result);
1772 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001773
Antoine Pitroud1188562010-06-09 16:38:55 +00001774 /* change everything in-place, starting with this one */
1775 start = result_s + (next-self_s);
1776 *start = to_c;
1777 start++;
1778 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001779
Antoine Pitroud1188562010-06-09 16:38:55 +00001780 while (--maxcount > 0) {
1781 next = findchar(start, end-start, from_c);
1782 if (next == NULL)
1783 break;
1784 *next = to_c;
1785 start = next+1;
1786 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001787
Antoine Pitroud1188562010-06-09 16:38:55 +00001788 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001789}
1790
1791/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1792Py_LOCAL(PyByteArrayObject *)
1793replace_substring_in_place(PyByteArrayObject *self,
1794 const char *from_s, Py_ssize_t from_len,
1795 const char *to_s, Py_ssize_t to_len,
1796 Py_ssize_t maxcount)
1797{
1798 char *result_s, *start, *end;
1799 char *self_s;
1800 Py_ssize_t self_len, offset;
1801 PyByteArrayObject *result;
1802
1803 /* The result bytes will be the same size */
1804
1805 self_s = PyByteArray_AS_STRING(self);
1806 self_len = PyByteArray_GET_SIZE(self);
1807
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001808 offset = stringlib_find(self_s, self_len,
1809 from_s, from_len,
1810 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001811 if (offset == -1) {
1812 /* No matches; return the original bytes */
1813 return return_self(self);
1814 }
1815
1816 /* Need to make a new bytes */
1817 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1818 if (result == NULL)
1819 return NULL;
1820 result_s = PyByteArray_AS_STRING(result);
1821 Py_MEMCPY(result_s, self_s, self_len);
1822
1823 /* change everything in-place, starting with this one */
1824 start = result_s + offset;
1825 Py_MEMCPY(start, to_s, from_len);
1826 start += from_len;
1827 end = result_s + self_len;
1828
1829 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001830 offset = stringlib_find(start, end-start,
1831 from_s, from_len,
1832 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001833 if (offset==-1)
1834 break;
1835 Py_MEMCPY(start+offset, to_s, from_len);
1836 start += offset+from_len;
1837 }
1838
1839 return result;
1840}
1841
1842/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1843Py_LOCAL(PyByteArrayObject *)
1844replace_single_character(PyByteArrayObject *self,
1845 char from_c,
1846 const char *to_s, Py_ssize_t to_len,
1847 Py_ssize_t maxcount)
1848{
1849 char *self_s, *result_s;
1850 char *start, *next, *end;
1851 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001852 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001853 PyByteArrayObject *result;
1854
1855 self_s = PyByteArray_AS_STRING(self);
1856 self_len = PyByteArray_GET_SIZE(self);
1857
1858 count = countchar(self_s, self_len, from_c, maxcount);
1859 if (count == 0) {
1860 /* no matches, return unchanged */
1861 return return_self(self);
1862 }
1863
1864 /* use the difference between current and new, hence the "-1" */
1865 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001866 assert(count > 0);
1867 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001868 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1869 return NULL;
1870 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001871 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001872
1873 if ( (result = (PyByteArrayObject *)
1874 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1875 return NULL;
1876 result_s = PyByteArray_AS_STRING(result);
1877
1878 start = self_s;
1879 end = self_s + self_len;
1880 while (count-- > 0) {
1881 next = findchar(start, end-start, from_c);
1882 if (next == NULL)
1883 break;
1884
1885 if (next == start) {
1886 /* replace with the 'to' */
1887 Py_MEMCPY(result_s, to_s, to_len);
1888 result_s += to_len;
1889 start += 1;
1890 } else {
1891 /* copy the unchanged old then the 'to' */
1892 Py_MEMCPY(result_s, start, next-start);
1893 result_s += (next-start);
1894 Py_MEMCPY(result_s, to_s, to_len);
1895 result_s += to_len;
1896 start = next+1;
1897 }
1898 }
1899 /* Copy the remainder of the remaining bytes */
1900 Py_MEMCPY(result_s, start, end-start);
1901
1902 return result;
1903}
1904
1905/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1906Py_LOCAL(PyByteArrayObject *)
1907replace_substring(PyByteArrayObject *self,
1908 const char *from_s, Py_ssize_t from_len,
1909 const char *to_s, Py_ssize_t to_len,
1910 Py_ssize_t maxcount)
1911{
1912 char *self_s, *result_s;
1913 char *start, *next, *end;
1914 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001915 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001916 PyByteArrayObject *result;
1917
1918 self_s = PyByteArray_AS_STRING(self);
1919 self_len = PyByteArray_GET_SIZE(self);
1920
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001921 count = stringlib_count(self_s, self_len,
1922 from_s, from_len,
1923 maxcount);
1924
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001925 if (count == 0) {
1926 /* no matches, return unchanged */
1927 return return_self(self);
1928 }
1929
1930 /* Check for overflow */
1931 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001932 assert(count > 0);
1933 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001934 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1935 return NULL;
1936 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001937 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001938
1939 if ( (result = (PyByteArrayObject *)
1940 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1941 return NULL;
1942 result_s = PyByteArray_AS_STRING(result);
1943
1944 start = self_s;
1945 end = self_s + self_len;
1946 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001947 offset = stringlib_find(start, end-start,
1948 from_s, from_len,
1949 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001950 if (offset == -1)
1951 break;
1952 next = start+offset;
1953 if (next == start) {
1954 /* replace with the 'to' */
1955 Py_MEMCPY(result_s, to_s, to_len);
1956 result_s += to_len;
1957 start += from_len;
1958 } else {
1959 /* copy the unchanged old then the 'to' */
1960 Py_MEMCPY(result_s, start, next-start);
1961 result_s += (next-start);
1962 Py_MEMCPY(result_s, to_s, to_len);
1963 result_s += to_len;
1964 start = next+from_len;
1965 }
1966 }
1967 /* Copy the remainder of the remaining bytes */
1968 Py_MEMCPY(result_s, start, end-start);
1969
1970 return result;
1971}
1972
1973
1974Py_LOCAL(PyByteArrayObject *)
1975replace(PyByteArrayObject *self,
1976 const char *from_s, Py_ssize_t from_len,
1977 const char *to_s, Py_ssize_t to_len,
1978 Py_ssize_t maxcount)
1979{
1980 if (maxcount < 0) {
1981 maxcount = PY_SSIZE_T_MAX;
1982 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1983 /* nothing to do; return the original bytes */
1984 return return_self(self);
1985 }
1986
1987 if (maxcount == 0 ||
1988 (from_len == 0 && to_len == 0)) {
1989 /* nothing to do; return the original bytes */
1990 return return_self(self);
1991 }
1992
1993 /* Handle zero-length special cases */
1994
1995 if (from_len == 0) {
1996 /* insert the 'to' bytes everywhere. */
1997 /* >>> "Python".replace("", ".") */
1998 /* '.P.y.t.h.o.n.' */
1999 return replace_interleave(self, to_s, to_len, maxcount);
2000 }
2001
2002 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2003 /* point for an empty self bytes to generate a non-empty bytes */
2004 /* Special case so the remaining code always gets a non-empty bytes */
2005 if (PyByteArray_GET_SIZE(self) == 0) {
2006 return return_self(self);
2007 }
2008
2009 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002010 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002011 if (from_len == 1) {
2012 return replace_delete_single_character(
2013 self, from_s[0], maxcount);
2014 } else {
2015 return replace_delete_substring(self, from_s, from_len, maxcount);
2016 }
2017 }
2018
2019 /* Handle special case where both bytes have the same length */
2020
2021 if (from_len == to_len) {
2022 if (from_len == 1) {
2023 return replace_single_character_in_place(
2024 self,
2025 from_s[0],
2026 to_s[0],
2027 maxcount);
2028 } else {
2029 return replace_substring_in_place(
2030 self, from_s, from_len, to_s, to_len, maxcount);
2031 }
2032 }
2033
2034 /* Otherwise use the more generic algorithms */
2035 if (from_len == 1) {
2036 return replace_single_character(self, from_s[0],
2037 to_s, to_len, maxcount);
2038 } else {
2039 /* len('from')>=2, len('to')>=1 */
2040 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2041 }
2042}
2043
2044
2045PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002046"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002047\n\
2048Return a copy of B with all occurrences of subsection\n\
2049old replaced by new. If the optional argument count is\n\
2050given, only the first count occurrences are replaced.");
2051
2052static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002053bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002054{
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002055 PyObject *res;
2056 Py_buffer old = {NULL, NULL};
2057 Py_buffer new = {NULL, NULL};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002058 Py_ssize_t count = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002059
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002060 if (!PyArg_ParseTuple(args, "y*y*|n:replace", &old, &new, &count))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002061 return NULL;
2062
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002063 res = (PyObject *)replace((PyByteArrayObject *) self,
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002064 (const char *)old.buf, old.len,
2065 (const char *)new.buf, new.len, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002066
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002067 PyBuffer_Release(&old);
2068 PyBuffer_Release(&new);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002069 return res;
2070}
2071
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002072PyDoc_STRVAR(split__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002073"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002074\n\
2075Return a list of the sections in B, using sep as the delimiter.\n\
2076If sep is not given, B is split on ASCII whitespace characters\n\
2077(space, tab, return, newline, formfeed, vertical tab).\n\
2078If maxsplit is given, at most maxsplit splits are done.");
2079
2080static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002081bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002082{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002083 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002084 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2085 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002086 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002087 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002088 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002089
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002090 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
2091 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002092 return NULL;
2093 if (maxsplit < 0)
2094 maxsplit = PY_SSIZE_T_MAX;
2095
2096 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002097 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002098
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002099 if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002100 return NULL;
2101 sub = vsub.buf;
2102 n = vsub.len;
2103
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002104 list = stringlib_split(
2105 (PyObject*) self, s, len, sub, n, maxsplit
2106 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002107 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002108 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002109}
2110
2111PyDoc_STRVAR(partition__doc__,
2112"B.partition(sep) -> (head, sep, tail)\n\
2113\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002114Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002115the separator itself, and the part after it. If the separator is not\n\
2116found, returns B and two empty bytearray objects.");
2117
2118static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002119bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002120{
2121 PyObject *bytesep, *result;
2122
2123 bytesep = PyByteArray_FromObject(sep_obj);
2124 if (! bytesep)
2125 return NULL;
2126
2127 result = stringlib_partition(
2128 (PyObject*) self,
2129 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2130 bytesep,
2131 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2132 );
2133
2134 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002135 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002136}
2137
2138PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002139"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002140\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002141Search for the separator sep in B, starting at the end of B,\n\
2142and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002143part after it. If the separator is not found, returns two empty\n\
2144bytearray objects and B.");
2145
2146static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002147bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002148{
2149 PyObject *bytesep, *result;
2150
2151 bytesep = PyByteArray_FromObject(sep_obj);
2152 if (! bytesep)
2153 return NULL;
2154
2155 result = stringlib_rpartition(
2156 (PyObject*) self,
2157 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2158 bytesep,
2159 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2160 );
2161
2162 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002163 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002164}
2165
2166PyDoc_STRVAR(rsplit__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002167"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002168\n\
2169Return a list of the sections in B, using sep as the delimiter,\n\
2170starting at the end of B and working to the front.\n\
2171If sep is not given, B is split on ASCII whitespace characters\n\
2172(space, tab, return, newline, formfeed, vertical tab).\n\
2173If maxsplit is given, at most maxsplit splits are done.");
2174
2175static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002176bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002177{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002178 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002179 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2180 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002181 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002182 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002183 Py_buffer vsub;
2184
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002185 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit",
2186 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002187 return NULL;
2188 if (maxsplit < 0)
2189 maxsplit = PY_SSIZE_T_MAX;
2190
2191 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002192 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002193
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002194 if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002195 return NULL;
2196 sub = vsub.buf;
2197 n = vsub.len;
2198
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002199 list = stringlib_rsplit(
2200 (PyObject*) self, s, len, sub, n, maxsplit
2201 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002202 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002203 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002204}
2205
2206PyDoc_STRVAR(reverse__doc__,
2207"B.reverse() -> None\n\
2208\n\
2209Reverse the order of the values in B in place.");
2210static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002211bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002212{
2213 char swap, *head, *tail;
2214 Py_ssize_t i, j, n = Py_SIZE(self);
2215
2216 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002217 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002218 tail = head + n - 1;
2219 for (i = 0; i < j; i++) {
2220 swap = *head;
2221 *head++ = *tail;
2222 *tail-- = swap;
2223 }
2224
2225 Py_RETURN_NONE;
2226}
2227
2228PyDoc_STRVAR(insert__doc__,
2229"B.insert(index, int) -> None\n\
2230\n\
2231Insert a single item into the bytearray before the given index.");
2232static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002233bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002234{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002235 PyObject *value;
2236 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002237 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002238 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002239
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002240 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002241 return NULL;
2242
2243 if (n == PY_SSIZE_T_MAX) {
2244 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002245 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002246 return NULL;
2247 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002248 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002249 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002250 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2251 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002252 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002253
2254 if (where < 0) {
2255 where += n;
2256 if (where < 0)
2257 where = 0;
2258 }
2259 if (where > n)
2260 where = n;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002261 memmove(buf + where + 1, buf + where, n - where);
2262 buf[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002263
2264 Py_RETURN_NONE;
2265}
2266
2267PyDoc_STRVAR(append__doc__,
2268"B.append(int) -> None\n\
2269\n\
2270Append a single item to the end of B.");
2271static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002272bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002273{
2274 int value;
2275 Py_ssize_t n = Py_SIZE(self);
2276
2277 if (! _getbytevalue(arg, &value))
2278 return NULL;
2279 if (n == PY_SSIZE_T_MAX) {
2280 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002281 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002282 return NULL;
2283 }
2284 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2285 return NULL;
2286
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002287 PyByteArray_AS_STRING(self)[n] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002288
2289 Py_RETURN_NONE;
2290}
2291
2292PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002293"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002294\n\
2295Append all the elements from the iterator or sequence to the\n\
2296end of B.");
2297static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002298bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002299{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002300 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002301 Py_ssize_t buf_size = 0, len = 0;
2302 int value;
2303 char *buf;
2304
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002305 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002306 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002307 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002308 return NULL;
2309
2310 Py_RETURN_NONE;
2311 }
2312
2313 it = PyObject_GetIter(arg);
2314 if (it == NULL)
2315 return NULL;
2316
Ezio Melotti42da6632011-03-15 05:18:48 +02002317 /* Try to determine the length of the argument. 32 is arbitrary. */
Armin Ronacheraa9a79d2012-10-06 14:03:24 +02002318 buf_size = PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002319 if (buf_size == -1) {
2320 Py_DECREF(it);
2321 return NULL;
2322 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002323
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002324 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002325 if (bytearray_obj == NULL) {
2326 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002327 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002328 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002329 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002330
2331 while ((item = PyIter_Next(it)) != NULL) {
2332 if (! _getbytevalue(item, &value)) {
2333 Py_DECREF(item);
2334 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002335 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002336 return NULL;
2337 }
2338 buf[len++] = value;
2339 Py_DECREF(item);
2340
2341 if (len >= buf_size) {
2342 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002343 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002344 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002345 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002346 return NULL;
2347 }
2348 /* Recompute the `buf' pointer, since the resizing operation may
2349 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002350 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002351 }
2352 }
2353 Py_DECREF(it);
2354
2355 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002356 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2357 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002358 return NULL;
2359 }
2360
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002361 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2362 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002363 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002364 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002365 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002366
2367 Py_RETURN_NONE;
2368}
2369
2370PyDoc_STRVAR(pop__doc__,
2371"B.pop([index]) -> int\n\
2372\n\
2373Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002374argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002375static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002376bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002377{
2378 int value;
2379 Py_ssize_t where = -1, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002380 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002381
2382 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2383 return NULL;
2384
2385 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002386 PyErr_SetString(PyExc_IndexError,
2387 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002388 return NULL;
2389 }
2390 if (where < 0)
2391 where += Py_SIZE(self);
2392 if (where < 0 || where >= Py_SIZE(self)) {
2393 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2394 return NULL;
2395 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002396 if (!_canresize(self))
2397 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002398
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002399 buf = PyByteArray_AS_STRING(self);
2400 value = buf[where];
2401 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002402 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2403 return NULL;
2404
Mark Dickinson54a3db92009-09-06 10:19:23 +00002405 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002406}
2407
2408PyDoc_STRVAR(remove__doc__,
2409"B.remove(int) -> None\n\
2410\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002411Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002412static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002413bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002414{
2415 int value;
2416 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002417 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002418
2419 if (! _getbytevalue(arg, &value))
2420 return NULL;
2421
2422 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002423 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002424 break;
2425 }
2426 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002427 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002428 return NULL;
2429 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002430 if (!_canresize(self))
2431 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002432
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002433 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002434 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2435 return NULL;
2436
2437 Py_RETURN_NONE;
2438}
2439
2440/* XXX These two helpers could be optimized if argsize == 1 */
2441
2442static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002443lstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002444 void *argptr, Py_ssize_t argsize)
2445{
2446 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002447 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002448 i++;
2449 return i;
2450}
2451
2452static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002453rstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002454 void *argptr, Py_ssize_t argsize)
2455{
2456 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002457 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002458 i--;
2459 return i + 1;
2460}
2461
2462PyDoc_STRVAR(strip__doc__,
2463"B.strip([bytes]) -> bytearray\n\
2464\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002465Strip leading and trailing bytes contained in the argument\n\
2466and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002467If the argument is omitted, strip ASCII whitespace.");
2468static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002469bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002470{
2471 Py_ssize_t left, right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002472 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002473 PyObject *arg = Py_None;
2474 Py_buffer varg;
2475 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2476 return NULL;
2477 if (arg == Py_None) {
2478 argptr = "\t\n\r\f\v ";
2479 argsize = 6;
2480 }
2481 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002482 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002483 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002484 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002485 argsize = varg.len;
2486 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002487 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002488 mysize = Py_SIZE(self);
2489 left = lstrip_helper(myptr, mysize, argptr, argsize);
2490 if (left == mysize)
2491 right = left;
2492 else
2493 right = rstrip_helper(myptr, mysize, argptr, argsize);
2494 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002495 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002496 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002497}
2498
2499PyDoc_STRVAR(lstrip__doc__,
2500"B.lstrip([bytes]) -> bytearray\n\
2501\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002502Strip leading bytes contained in the argument\n\
2503and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002504If the argument is omitted, strip leading ASCII whitespace.");
2505static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002506bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002507{
2508 Py_ssize_t left, right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002509 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002510 PyObject *arg = Py_None;
2511 Py_buffer varg;
2512 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2513 return NULL;
2514 if (arg == Py_None) {
2515 argptr = "\t\n\r\f\v ";
2516 argsize = 6;
2517 }
2518 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002519 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002520 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002521 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002522 argsize = varg.len;
2523 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002524 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002525 mysize = Py_SIZE(self);
2526 left = lstrip_helper(myptr, mysize, argptr, argsize);
2527 right = mysize;
2528 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002529 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002530 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002531}
2532
2533PyDoc_STRVAR(rstrip__doc__,
2534"B.rstrip([bytes]) -> bytearray\n\
2535\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002536Strip trailing bytes contained in the argument\n\
2537and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002538If the argument is omitted, strip trailing ASCII whitespace.");
2539static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002540bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002541{
Brett Cannonb94767f2011-02-22 20:15:44 +00002542 Py_ssize_t right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002543 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002544 PyObject *arg = Py_None;
2545 Py_buffer varg;
2546 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2547 return NULL;
2548 if (arg == Py_None) {
2549 argptr = "\t\n\r\f\v ";
2550 argsize = 6;
2551 }
2552 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002553 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002554 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002555 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002556 argsize = varg.len;
2557 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002558 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002559 mysize = Py_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002560 right = rstrip_helper(myptr, mysize, argptr, argsize);
2561 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002562 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002563 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002564}
2565
2566PyDoc_STRVAR(decode_doc,
Victor Stinnerc911bbf2010-11-07 19:04:46 +00002567"B.decode(encoding='utf-8', errors='strict') -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002568\n\
Victor Stinnere14e2122010-11-07 18:41:46 +00002569Decode B using the codec registered for encoding. Default encoding\n\
2570is 'utf-8'. errors may be given to set a different error\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002571handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2572a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2573as well as any other name registered with codecs.register_error that is\n\
2574able to handle UnicodeDecodeErrors.");
2575
2576static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002577bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002578{
2579 const char *encoding = NULL;
2580 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002581 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002582
Benjamin Peterson308d6372009-09-18 21:42:35 +00002583 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002584 return NULL;
2585 if (encoding == NULL)
2586 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002587 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002588}
2589
2590PyDoc_STRVAR(alloc_doc,
2591"B.__alloc__() -> int\n\
2592\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002593Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002594
2595static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002596bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002597{
2598 return PyLong_FromSsize_t(self->ob_alloc);
2599}
2600
2601PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002602"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002603\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002604Concatenate any number of bytes/bytearray objects, with B\n\
2605in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002606
2607static PyObject *
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002608bytearray_join(PyObject *self, PyObject *iterable)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002609{
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002610 return stringlib_bytes_join(self, iterable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002611}
2612
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002613PyDoc_STRVAR(splitlines__doc__,
2614"B.splitlines([keepends]) -> list of lines\n\
2615\n\
2616Return a list of the lines in B, breaking at line boundaries.\n\
2617Line breaks are not included in the resulting list unless keepends\n\
2618is given and true.");
2619
2620static PyObject*
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002621bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002622{
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002623 static char *kwlist[] = {"keepends", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002624 int keepends = 0;
2625
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002626 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines",
2627 kwlist, &keepends))
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002628 return NULL;
2629
2630 return stringlib_splitlines(
2631 (PyObject*) self, PyByteArray_AS_STRING(self),
2632 PyByteArray_GET_SIZE(self), keepends
2633 );
2634}
2635
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002636PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002637"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002638\n\
2639Create a bytearray object from a string of hexadecimal numbers.\n\
2640Spaces between two numbers are accepted.\n\
2641Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2642
2643static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002644hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002645{
2646 if (c >= 128)
2647 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002648 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002649 return c - '0';
2650 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002651 if (Py_ISUPPER(c))
2652 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002653 if (c >= 'a' && c <= 'f')
2654 return c - 'a' + 10;
2655 }
2656 return -1;
2657}
2658
2659static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002660bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002661{
2662 PyObject *newbytes, *hexobj;
2663 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002664 Py_ssize_t hexlen, byteslen, i, j;
2665 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002666 void *data;
2667 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002668
2669 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2670 return NULL;
2671 assert(PyUnicode_Check(hexobj));
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002672 if (PyUnicode_READY(hexobj))
2673 return NULL;
2674 kind = PyUnicode_KIND(hexobj);
2675 data = PyUnicode_DATA(hexobj);
2676 hexlen = PyUnicode_GET_LENGTH(hexobj);
2677
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002678 byteslen = hexlen/2; /* This overestimates if there are spaces */
2679 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2680 if (!newbytes)
2681 return NULL;
2682 buf = PyByteArray_AS_STRING(newbytes);
2683 for (i = j = 0; i < hexlen; i += 2) {
2684 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002685 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002686 i++;
2687 if (i >= hexlen)
2688 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002689 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2690 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002691 if (top == -1 || bot == -1) {
2692 PyErr_Format(PyExc_ValueError,
2693 "non-hexadecimal number found in "
2694 "fromhex() arg at position %zd", i);
2695 goto error;
2696 }
2697 buf[j++] = (top << 4) + bot;
2698 }
2699 if (PyByteArray_Resize(newbytes, j) < 0)
2700 goto error;
2701 return newbytes;
2702
2703 error:
2704 Py_DECREF(newbytes);
2705 return NULL;
2706}
2707
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002708
2709static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002710_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002711{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002712 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002713 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002714 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002715
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002716 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002717 if (dict == NULL) {
2718 PyErr_Clear();
2719 dict = Py_None;
2720 Py_INCREF(dict);
2721 }
2722
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002723 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002724 if (proto < 3) {
2725 /* use str based reduction for backwards compatibility with Python 2.x */
2726 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002727 if (Py_SIZE(self))
2728 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002729 else
2730 latin1 = PyUnicode_FromString("");
2731 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2732 }
2733 else {
2734 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002735 if (Py_SIZE(self)) {
2736 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002737 }
2738 else {
2739 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2740 }
2741 }
2742}
2743
2744PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2745
2746static PyObject *
2747bytearray_reduce(PyByteArrayObject *self)
2748{
2749 return _common_reduce(self, 2);
2750}
2751
2752PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling.");
2753
2754static PyObject *
2755bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
2756{
2757 int proto = 0;
2758
2759 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
2760 return NULL;
2761
2762 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002763}
2764
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002765PyDoc_STRVAR(sizeof_doc,
2766"B.__sizeof__() -> int\n\
2767 \n\
2768Returns the size of B in memory, in bytes");
2769static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002770bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002771{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002772 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002773
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002774 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2775 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002776}
2777
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002778static PySequenceMethods bytearray_as_sequence = {
2779 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002780 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002781 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2782 (ssizeargfunc)bytearray_getitem, /* sq_item */
2783 0, /* sq_slice */
2784 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2785 0, /* sq_ass_slice */
2786 (objobjproc)bytearray_contains, /* sq_contains */
2787 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2788 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002789};
2790
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002791static PyMappingMethods bytearray_as_mapping = {
2792 (lenfunc)bytearray_length,
2793 (binaryfunc)bytearray_subscript,
2794 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002795};
2796
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002797static PyBufferProcs bytearray_as_buffer = {
2798 (getbufferproc)bytearray_getbuffer,
2799 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002800};
2801
2802static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002803bytearray_methods[] = {
2804 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2805 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002806 {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002807 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2808 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002809 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2810 _Py_capitalize__doc__},
2811 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00002812 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__},
2813 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002814 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002815 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002816 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Ezio Melotti745d54d2013-11-16 19:10:57 +02002817 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002818 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002819 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2820 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2821 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002822 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002823 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2824 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002825 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2826 _Py_isalnum__doc__},
2827 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2828 _Py_isalpha__doc__},
2829 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2830 _Py_isdigit__doc__},
2831 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2832 _Py_islower__doc__},
2833 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2834 _Py_isspace__doc__},
2835 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2836 _Py_istitle__doc__},
2837 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2838 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002839 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002840 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2841 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002842 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2843 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002844 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002845 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2846 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2847 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2848 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2849 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2850 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2851 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002852 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002853 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002854 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002855 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002856 {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__},
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002857 {"splitlines", (PyCFunction)bytearray_splitlines,
2858 METH_VARARGS | METH_KEYWORDS, splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002859 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002860 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002861 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002862 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2863 _Py_swapcase__doc__},
2864 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002865 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002866 translate__doc__},
2867 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2868 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2869 {NULL}
2870};
2871
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002872PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002873"bytearray(iterable_of_ints) -> bytearray\n\
2874bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002875bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2876bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2877bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002878\n\
2879Construct an mutable bytearray object from:\n\
2880 - an iterable yielding integers in range(256)\n\
2881 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002882 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002883 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002884 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002885
2886
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002887static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002888
2889PyTypeObject PyByteArray_Type = {
2890 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2891 "bytearray",
2892 sizeof(PyByteArrayObject),
2893 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002894 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002895 0, /* tp_print */
2896 0, /* tp_getattr */
2897 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002898 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002899 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002900 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002901 &bytearray_as_sequence, /* tp_as_sequence */
2902 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002903 0, /* tp_hash */
2904 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002905 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002906 PyObject_GenericGetAttr, /* tp_getattro */
2907 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002908 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002909 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002910 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002911 0, /* tp_traverse */
2912 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002913 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002914 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002915 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002916 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002917 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002918 0, /* tp_members */
2919 0, /* tp_getset */
2920 0, /* tp_base */
2921 0, /* tp_dict */
2922 0, /* tp_descr_get */
2923 0, /* tp_descr_set */
2924 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002925 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002926 PyType_GenericAlloc, /* tp_alloc */
2927 PyType_GenericNew, /* tp_new */
2928 PyObject_Del, /* tp_free */
2929};
2930
2931/*********************** Bytes Iterator ****************************/
2932
2933typedef struct {
2934 PyObject_HEAD
2935 Py_ssize_t it_index;
2936 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2937} bytesiterobject;
2938
2939static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002940bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002941{
2942 _PyObject_GC_UNTRACK(it);
2943 Py_XDECREF(it->it_seq);
2944 PyObject_GC_Del(it);
2945}
2946
2947static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002948bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002949{
2950 Py_VISIT(it->it_seq);
2951 return 0;
2952}
2953
2954static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002955bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002956{
2957 PyByteArrayObject *seq;
2958 PyObject *item;
2959
2960 assert(it != NULL);
2961 seq = it->it_seq;
2962 if (seq == NULL)
2963 return NULL;
2964 assert(PyByteArray_Check(seq));
2965
2966 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2967 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002968 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002969 if (item != NULL)
2970 ++it->it_index;
2971 return item;
2972 }
2973
2974 Py_DECREF(seq);
2975 it->it_seq = NULL;
2976 return NULL;
2977}
2978
2979static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002980bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002981{
2982 Py_ssize_t len = 0;
2983 if (it->it_seq)
2984 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2985 return PyLong_FromSsize_t(len);
2986}
2987
2988PyDoc_STRVAR(length_hint_doc,
2989 "Private method returning an estimate of len(list(it)).");
2990
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002991static PyObject *
2992bytearrayiter_reduce(bytesiterobject *it)
2993{
2994 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02002995 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002996 it->it_seq, it->it_index);
2997 } else {
2998 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
2999 if (u == NULL)
3000 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02003001 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003002 }
3003}
3004
3005static PyObject *
3006bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3007{
3008 Py_ssize_t index = PyLong_AsSsize_t(state);
3009 if (index == -1 && PyErr_Occurred())
3010 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +00003011 if (it->it_seq != NULL) {
3012 if (index < 0)
3013 index = 0;
3014 else if (index > PyByteArray_GET_SIZE(it->it_seq))
3015 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
3016 it->it_index = index;
3017 }
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003018 Py_RETURN_NONE;
3019}
3020
3021PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3022
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003023static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003024 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003025 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003026 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
3027 reduce_doc},
3028 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3029 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003030 {NULL, NULL} /* sentinel */
3031};
3032
3033PyTypeObject PyByteArrayIter_Type = {
3034 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3035 "bytearray_iterator", /* tp_name */
3036 sizeof(bytesiterobject), /* tp_basicsize */
3037 0, /* tp_itemsize */
3038 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003039 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003040 0, /* tp_print */
3041 0, /* tp_getattr */
3042 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003043 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003044 0, /* tp_repr */
3045 0, /* tp_as_number */
3046 0, /* tp_as_sequence */
3047 0, /* tp_as_mapping */
3048 0, /* tp_hash */
3049 0, /* tp_call */
3050 0, /* tp_str */
3051 PyObject_GenericGetAttr, /* tp_getattro */
3052 0, /* tp_setattro */
3053 0, /* tp_as_buffer */
3054 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3055 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003056 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003057 0, /* tp_clear */
3058 0, /* tp_richcompare */
3059 0, /* tp_weaklistoffset */
3060 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003061 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3062 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003063 0,
3064};
3065
3066static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003067bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003068{
3069 bytesiterobject *it;
3070
3071 if (!PyByteArray_Check(seq)) {
3072 PyErr_BadInternalCall();
3073 return NULL;
3074 }
3075 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3076 if (it == NULL)
3077 return NULL;
3078 it->it_index = 0;
3079 Py_INCREF(seq);
3080 it->it_seq = (PyByteArrayObject *)seq;
3081 _PyObject_GC_TRACK(it);
3082 return (PyObject *)it;
3083}