blob: 15c525c44224d30cd115cbdcf3f3ba28c66154cb [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 Pitrou25454112015-05-19 20:52:27 +0200182 if (size + logical_offset + 1 <= alloc) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200183 /* 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 }
Antoine Pitrou25454112015-05-19 20:52:27 +0200301 if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000302 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000303 return NULL;
304 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200305 memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000306 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000307 Py_INCREF(self);
308 return (PyObject *)self;
309}
310
311static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000312bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000313{
314 PyByteArrayObject *result;
315 Py_ssize_t mysize;
316 Py_ssize_t size;
317
318 if (count < 0)
319 count = 0;
320 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000321 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000322 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000323 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000324 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
325 if (result != NULL && size != 0) {
326 if (mysize == 1)
327 memset(result->ob_bytes, self->ob_bytes[0], size);
328 else {
329 Py_ssize_t i;
330 for (i = 0; i < count; i++)
331 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
332 }
333 }
334 return (PyObject *)result;
335}
336
337static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000338bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000339{
340 Py_ssize_t mysize;
341 Py_ssize_t size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200342 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000343
344 if (count < 0)
345 count = 0;
346 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000347 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000348 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000349 size = mysize * count;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200350 if (PyByteArray_Resize((PyObject *)self, size) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000351 return NULL;
352
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200353 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000354 if (mysize == 1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200355 memset(buf, buf[0], size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000356 else {
357 Py_ssize_t i;
358 for (i = 1; i < count; i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200359 memcpy(buf + i*mysize, buf, mysize);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000360 }
361
362 Py_INCREF(self);
363 return (PyObject *)self;
364}
365
366static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000367bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000368{
369 if (i < 0)
370 i += Py_SIZE(self);
371 if (i < 0 || i >= Py_SIZE(self)) {
372 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
373 return NULL;
374 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200375 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000376}
377
378static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000379bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000380{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000381 if (PyIndex_Check(index)) {
382 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000383
384 if (i == -1 && PyErr_Occurred())
385 return NULL;
386
387 if (i < 0)
388 i += PyByteArray_GET_SIZE(self);
389
390 if (i < 0 || i >= Py_SIZE(self)) {
391 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
392 return NULL;
393 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200394 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000395 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000396 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000397 Py_ssize_t start, stop, step, slicelength, cur, i;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000398 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000399 PyByteArray_GET_SIZE(self),
400 &start, &stop, &step, &slicelength) < 0) {
401 return NULL;
402 }
403
404 if (slicelength <= 0)
405 return PyByteArray_FromStringAndSize("", 0);
406 else if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200407 return PyByteArray_FromStringAndSize(
408 PyByteArray_AS_STRING(self) + start, slicelength);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000409 }
410 else {
411 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000412 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000413 PyObject *result;
414
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000415 result = PyByteArray_FromStringAndSize(NULL, slicelength);
416 if (result == NULL)
417 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000418
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000419 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000420 for (cur = start, i = 0; i < slicelength;
421 cur += step, i++) {
422 result_buf[i] = source_buf[cur];
423 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000424 return result;
425 }
426 }
427 else {
428 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
429 return NULL;
430 }
431}
432
433static int
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200434bytearray_setslice_linear(PyByteArrayObject *self,
435 Py_ssize_t lo, Py_ssize_t hi,
436 char *bytes, Py_ssize_t bytes_len)
437{
438 Py_ssize_t avail = hi - lo;
439 char *buf = PyByteArray_AS_STRING(self);
440 Py_ssize_t growth = bytes_len - avail;
Victor Stinner84557232013-11-21 12:29:51 +0100441 int res = 0;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200442 assert(avail >= 0);
443
Victor Stinner84557232013-11-21 12:29:51 +0100444 if (growth < 0) {
445 if (!_canresize(self))
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200446 return -1;
Victor Stinner84557232013-11-21 12:29:51 +0100447
448 if (lo == 0) {
449 /* Shrink the buffer by advancing its logical start */
450 self->ob_start -= growth;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200451 /*
Victor Stinner84557232013-11-21 12:29:51 +0100452 0 lo hi old_size
453 | |<----avail----->|<-----tail------>|
454 | |<-bytes_len->|<-----tail------>|
455 0 new_lo new_hi new_size
456 */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200457 }
Victor Stinner84557232013-11-21 12:29:51 +0100458 else {
459 /*
460 0 lo hi old_size
461 | |<----avail----->|<-----tomove------>|
462 | |<-bytes_len->|<-----tomove------>|
463 0 lo new_hi new_size
464 */
465 memmove(buf + lo + bytes_len, buf + hi,
466 Py_SIZE(self) - hi);
467 }
468 if (PyByteArray_Resize((PyObject *)self,
469 Py_SIZE(self) + growth) < 0) {
470 /* Issue #19578: Handling the memory allocation failure here is
471 tricky here because the bytearray object has already been
472 modified. Depending on growth and lo, the behaviour is
473 different.
474
475 If growth < 0 and lo != 0, the operation is completed, but a
476 MemoryError is still raised and the memory block is not
477 shrinked. Otherwise, the bytearray is restored in its previous
478 state and a MemoryError is raised. */
479 if (lo == 0) {
480 self->ob_start += growth;
481 return -1;
482 }
483 /* memmove() removed bytes, the bytearray object cannot be
484 restored in its previous state. */
485 Py_SIZE(self) += growth;
486 res = -1;
487 }
488 buf = PyByteArray_AS_STRING(self);
489 }
490 else if (growth > 0) {
491 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
492 PyErr_NoMemory();
493 return -1;
494 }
495
496 if (PyByteArray_Resize((PyObject *)self,
497 Py_SIZE(self) + growth) < 0) {
498 return -1;
499 }
500 buf = PyByteArray_AS_STRING(self);
501 /* Make the place for the additional bytes */
502 /*
503 0 lo hi old_size
504 | |<-avail->|<-----tomove------>|
505 | |<---bytes_len-->|<-----tomove------>|
506 0 lo new_hi new_size
507 */
508 memmove(buf + lo + bytes_len, buf + hi,
509 Py_SIZE(self) - lo - bytes_len);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200510 }
511
512 if (bytes_len > 0)
513 memcpy(buf + lo, bytes, bytes_len);
Victor Stinner84557232013-11-21 12:29:51 +0100514 return res;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200515}
516
517static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000518bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000519 PyObject *values)
520{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200521 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000522 void *bytes;
523 Py_buffer vbytes;
524 int res = 0;
525
526 vbytes.len = -1;
527 if (values == (PyObject *)self) {
528 /* Make a copy and call this function recursively */
529 int err;
530 values = PyByteArray_FromObject(values);
531 if (values == NULL)
532 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000533 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000534 Py_DECREF(values);
535 return err;
536 }
537 if (values == NULL) {
538 /* del b[lo:hi] */
539 bytes = NULL;
540 needed = 0;
541 }
542 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200543 if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
544 PyErr_Format(PyExc_TypeError,
545 "can't set bytearray slice from %.100s",
546 Py_TYPE(values)->tp_name);
547 return -1;
548 }
549 needed = vbytes.len;
550 bytes = vbytes.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000551 }
552
553 if (lo < 0)
554 lo = 0;
555 if (hi < lo)
556 hi = lo;
557 if (hi > Py_SIZE(self))
558 hi = Py_SIZE(self);
559
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200560 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000561 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200562 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000563 return res;
564}
565
566static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000567bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000568{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000569 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000570
571 if (i < 0)
572 i += Py_SIZE(self);
573
574 if (i < 0 || i >= Py_SIZE(self)) {
575 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
576 return -1;
577 }
578
579 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000580 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000581
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000582 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000583 return -1;
584
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200585 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000586 return 0;
587}
588
589static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000590bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000591{
592 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200593 char *buf, *bytes;
594 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000595
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000596 if (PyIndex_Check(index)) {
597 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000598
599 if (i == -1 && PyErr_Occurred())
600 return -1;
601
602 if (i < 0)
603 i += PyByteArray_GET_SIZE(self);
604
605 if (i < 0 || i >= Py_SIZE(self)) {
606 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
607 return -1;
608 }
609
610 if (values == NULL) {
611 /* Fall through to slice assignment */
612 start = i;
613 stop = i + 1;
614 step = 1;
615 slicelen = 1;
616 }
617 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000618 int ival;
619 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000620 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200621 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000622 return 0;
623 }
624 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000625 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000626 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000627 PyByteArray_GET_SIZE(self),
628 &start, &stop, &step, &slicelen) < 0) {
629 return -1;
630 }
631 }
632 else {
633 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
634 return -1;
635 }
636
637 if (values == NULL) {
638 bytes = NULL;
639 needed = 0;
640 }
641 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100642 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200643 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
644 PyErr_SetString(PyExc_TypeError,
645 "can assign only bytes, buffers, or iterables "
646 "of ints in range(0, 256)");
647 return -1;
648 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000649 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000650 values = PyByteArray_FromObject(values);
651 if (values == NULL)
652 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000653 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000654 Py_DECREF(values);
655 return err;
656 }
657 else {
658 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200659 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000660 needed = Py_SIZE(values);
661 }
662 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
663 if ((step < 0 && start < stop) ||
664 (step > 0 && start > stop))
665 stop = start;
666 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200667 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000668 }
669 else {
670 if (needed == 0) {
671 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000672 size_t cur;
673 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000674
Antoine Pitrou5504e892008-12-06 21:27:53 +0000675 if (!_canresize(self))
676 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000677
678 if (slicelen == 0)
679 /* Nothing to do here. */
680 return 0;
681
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000682 if (step < 0) {
683 stop = start + 1;
684 start = stop + step * (slicelen - 1) - 1;
685 step = -step;
686 }
687 for (cur = start, i = 0;
688 i < slicelen; cur += step, i++) {
689 Py_ssize_t lim = step - 1;
690
Mark Dickinson66f575b2010-02-14 12:53:32 +0000691 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000692 lim = PyByteArray_GET_SIZE(self) - cur - 1;
693
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200694 memmove(buf + cur - i,
695 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000696 }
697 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000698 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000699 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200700 memmove(buf + cur - slicelen,
701 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000702 PyByteArray_GET_SIZE(self) - cur);
703 }
704 if (PyByteArray_Resize((PyObject *)self,
705 PyByteArray_GET_SIZE(self) - slicelen) < 0)
706 return -1;
707
708 return 0;
709 }
710 else {
711 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000712 Py_ssize_t i;
713 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000714
715 if (needed != slicelen) {
716 PyErr_Format(PyExc_ValueError,
717 "attempt to assign bytes of size %zd "
718 "to extended slice of size %zd",
719 needed, slicelen);
720 return -1;
721 }
722 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200723 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000724 return 0;
725 }
726 }
727}
728
729static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000730bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000731{
732 static char *kwlist[] = {"source", "encoding", "errors", 0};
733 PyObject *arg = NULL;
734 const char *encoding = NULL;
735 const char *errors = NULL;
736 Py_ssize_t count;
737 PyObject *it;
738 PyObject *(*iternext)(PyObject *);
739
740 if (Py_SIZE(self) != 0) {
741 /* Empty previous contents (yes, do this first of all!) */
742 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
743 return -1;
744 }
745
746 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000747 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000748 &arg, &encoding, &errors))
749 return -1;
750
751 /* Make a quick exit if no first argument */
752 if (arg == NULL) {
753 if (encoding != NULL || errors != NULL) {
754 PyErr_SetString(PyExc_TypeError,
755 "encoding or errors without sequence argument");
756 return -1;
757 }
758 return 0;
759 }
760
761 if (PyUnicode_Check(arg)) {
762 /* Encode via the codec registry */
763 PyObject *encoded, *new;
764 if (encoding == NULL) {
765 PyErr_SetString(PyExc_TypeError,
766 "string argument without an encoding");
767 return -1;
768 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000769 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000770 if (encoded == NULL)
771 return -1;
772 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000773 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000774 Py_DECREF(encoded);
775 if (new == NULL)
776 return -1;
777 Py_DECREF(new);
778 return 0;
779 }
780
781 /* If it's not unicode, there can't be encoding or errors */
782 if (encoding != NULL || errors != NULL) {
783 PyErr_SetString(PyExc_TypeError,
784 "encoding or errors without a string argument");
785 return -1;
786 }
787
788 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000789 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
790 if (count == -1 && PyErr_Occurred()) {
791 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000792 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000793 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000794 }
795 else if (count < 0) {
796 PyErr_SetString(PyExc_ValueError, "negative count");
797 return -1;
798 }
799 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000800 if (count > 0) {
801 if (PyByteArray_Resize((PyObject *)self, count))
802 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200803 memset(PyByteArray_AS_STRING(self), 0, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000804 }
805 return 0;
806 }
807
808 /* Use the buffer API */
809 if (PyObject_CheckBuffer(arg)) {
810 Py_ssize_t size;
811 Py_buffer view;
812 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
813 return -1;
814 size = view.len;
815 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200816 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
817 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200818 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000819 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000820 return 0;
821 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000822 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000823 return -1;
824 }
825
826 /* XXX Optimize this if the arguments is a list, tuple */
827
828 /* Get the iterator */
829 it = PyObject_GetIter(arg);
830 if (it == NULL)
831 return -1;
832 iternext = *Py_TYPE(it)->tp_iternext;
833
834 /* Run the iterator to exhaustion */
835 for (;;) {
836 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000837 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000838
839 /* Get the next item */
840 item = iternext(it);
841 if (item == NULL) {
842 if (PyErr_Occurred()) {
843 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
844 goto error;
845 PyErr_Clear();
846 }
847 break;
848 }
849
850 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000851 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000852 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000853 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000854 goto error;
855
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000856 /* Append the byte */
Serhiy Storchaka7b6e3b92015-06-29 21:14:06 +0300857 if (Py_SIZE(self) + 1 < self->ob_alloc) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000858 Py_SIZE(self)++;
Serhiy Storchaka7b6e3b92015-06-29 21:14:06 +0300859 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
860 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000861 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
862 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200863 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000864 }
865
866 /* Clean up and return success */
867 Py_DECREF(it);
868 return 0;
869
870 error:
871 /* Error handling when it != NULL */
872 Py_DECREF(it);
873 return -1;
874}
875
876/* Mostly copied from string_repr, but without the
877 "smart quote" functionality. */
878static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000879bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000880{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000881 const char *quote_prefix = "bytearray(b";
882 const char *quote_postfix = ")";
883 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200884 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000885 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000886 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200887 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200888 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200889 char c;
890 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200891 int quote;
892 char *test, *start;
893 char *buffer;
894
895 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000896 PyErr_SetString(PyExc_OverflowError,
897 "bytearray object is too large to make repr");
898 return NULL;
899 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200900
901 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100902 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200903 if (buffer == NULL) {
904 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000905 return NULL;
906 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000907
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200908 /* Figure out which quote to use; single is preferred */
909 quote = '\'';
910 start = PyByteArray_AS_STRING(self);
911 for (test = start; test < start+length; ++test) {
912 if (*test == '"') {
913 quote = '\''; /* back to single */
914 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000915 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200916 else if (*test == '\'')
917 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000918 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200919
920 p = buffer;
921 while (*quote_prefix)
922 *p++ = *quote_prefix++;
923 *p++ = quote;
924
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200925 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200926 for (i = 0; i < length; i++) {
927 /* There's at least enough room for a hex escape
928 and a closing quote. */
929 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200930 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200931 if (c == '\'' || c == '\\')
932 *p++ = '\\', *p++ = c;
933 else if (c == '\t')
934 *p++ = '\\', *p++ = 't';
935 else if (c == '\n')
936 *p++ = '\\', *p++ = 'n';
937 else if (c == '\r')
938 *p++ = '\\', *p++ = 'r';
939 else if (c == 0)
940 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
941 else if (c < ' ' || c >= 0x7f) {
942 *p++ = '\\';
943 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200944 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
945 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200946 }
947 else
948 *p++ = c;
949 }
950 assert(newsize - (p - buffer) >= 1);
951 *p++ = quote;
952 while (*quote_postfix) {
953 *p++ = *quote_postfix++;
954 }
955
956 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100957 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200958 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000959}
960
961static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000962bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000963{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000964 if (Py_BytesWarningFlag) {
965 if (PyErr_WarnEx(PyExc_BytesWarning,
966 "str() on a bytearray instance", 1))
967 return NULL;
968 }
969 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000970}
971
972static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000973bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000974{
975 Py_ssize_t self_size, other_size;
976 Py_buffer self_bytes, other_bytes;
977 PyObject *res;
978 Py_ssize_t minsize;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300979 int cmp, rc;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000980
981 /* Bytes can be compared to anything that supports the (binary)
982 buffer API. Except that a comparison with Unicode is always an
983 error, even if the comparison is for equality. */
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300984 rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type);
985 if (!rc)
986 rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type);
987 if (rc < 0)
988 return NULL;
989 if (rc) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000990 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000991 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000992 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000993 return NULL;
994 }
995
Brian Curtindfc80e32011-08-10 20:28:54 -0500996 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000997 }
998
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200999 if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001000 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -05001001 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001002 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001003 self_size = self_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001004
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001005 if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001006 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001007 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001008 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001009 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001010 other_size = other_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001011
1012 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1013 /* Shortcut: if the lengths differ, the objects differ */
1014 cmp = (op == Py_NE);
1015 }
1016 else {
1017 minsize = self_size;
1018 if (other_size < minsize)
1019 minsize = other_size;
1020
1021 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1022 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1023
1024 if (cmp == 0) {
1025 if (self_size < other_size)
1026 cmp = -1;
1027 else if (self_size > other_size)
1028 cmp = 1;
1029 }
1030
1031 switch (op) {
1032 case Py_LT: cmp = cmp < 0; break;
1033 case Py_LE: cmp = cmp <= 0; break;
1034 case Py_EQ: cmp = cmp == 0; break;
1035 case Py_NE: cmp = cmp != 0; break;
1036 case Py_GT: cmp = cmp > 0; break;
1037 case Py_GE: cmp = cmp >= 0; break;
1038 }
1039 }
1040
1041 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001042 PyBuffer_Release(&self_bytes);
1043 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001044 Py_INCREF(res);
1045 return res;
1046}
1047
1048static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001049bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001050{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001051 if (self->ob_exports > 0) {
1052 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001053 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001054 PyErr_Print();
1055 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001056 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001057 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001058 }
1059 Py_TYPE(self)->tp_free((PyObject *)self);
1060}
1061
1062
1063/* -------------------------------------------------------------------- */
1064/* Methods */
1065
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001066#define FASTSEARCH fastsearch
1067#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001068#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001069#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001070#define STRINGLIB_LEN PyByteArray_GET_SIZE
1071#define STRINGLIB_STR PyByteArray_AS_STRING
1072#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001073#define STRINGLIB_ISSPACE Py_ISSPACE
1074#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001075#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1076#define STRINGLIB_MUTABLE 1
1077
1078#include "stringlib/fastsearch.h"
1079#include "stringlib/count.h"
1080#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001081#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001082#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001083#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001084#include "stringlib/ctype.h"
1085#include "stringlib/transmogrify.h"
1086
1087
1088/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1089were copied from the old char* style string object. */
1090
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001091/* helper macro to fixup start/end slice values */
1092#define ADJUST_INDICES(start, end, len) \
1093 if (end > len) \
1094 end = len; \
1095 else if (end < 0) { \
1096 end += len; \
1097 if (end < 0) \
1098 end = 0; \
1099 } \
1100 if (start < 0) { \
1101 start += len; \
1102 if (start < 0) \
1103 start = 0; \
1104 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001105
1106Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001107bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001108{
1109 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001110 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001111 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001112 const char *sub;
1113 Py_ssize_t sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001114 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1115 Py_ssize_t res;
1116
Antoine Pitrouac65d962011-10-20 23:54:17 +02001117 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1118 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001119 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001120
1121 if (subobj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001122 if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001123 return -2;
1124
1125 sub = subbuf.buf;
1126 sub_len = subbuf.len;
1127 }
1128 else {
1129 sub = &byte;
1130 sub_len = 1;
1131 }
1132
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001133 if (dir > 0)
1134 res = stringlib_find_slice(
1135 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001136 sub, sub_len, start, end);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001137 else
1138 res = stringlib_rfind_slice(
1139 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001140 sub, sub_len, start, end);
1141
1142 if (subobj)
1143 PyBuffer_Release(&subbuf);
1144
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001145 return res;
1146}
1147
1148PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001149"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001150\n\
1151Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001152such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001153arguments start and end are interpreted as in slice notation.\n\
1154\n\
1155Return -1 on failure.");
1156
1157static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001158bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001159{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001160 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001161 if (result == -2)
1162 return NULL;
1163 return PyLong_FromSsize_t(result);
1164}
1165
1166PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001167"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001168\n\
1169Return the number of non-overlapping occurrences of subsection sub in\n\
1170bytes B[start:end]. Optional arguments start and end are interpreted\n\
1171as in slice notation.");
1172
1173static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001174bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001175{
1176 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001177 const char *str = PyByteArray_AS_STRING(self), *sub;
1178 Py_ssize_t sub_len;
1179 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001180 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001181
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001182 Py_buffer vsub;
1183 PyObject *count_obj;
1184
Antoine Pitrouac65d962011-10-20 23:54:17 +02001185 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1186 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001187 return NULL;
1188
Antoine Pitrouac65d962011-10-20 23:54:17 +02001189 if (sub_obj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001190 if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001191 return NULL;
1192
1193 sub = vsub.buf;
1194 sub_len = vsub.len;
1195 }
1196 else {
1197 sub = &byte;
1198 sub_len = 1;
1199 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001200
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001201 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001202
1203 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001204 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001205 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001206
1207 if (sub_obj)
1208 PyBuffer_Release(&vsub);
1209
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001210 return count_obj;
1211}
1212
Eli Bendersky4db28d32011-03-03 18:21:02 +00001213PyDoc_STRVAR(clear__doc__,
1214"B.clear() -> None\n\
1215\n\
1216Remove all items from B.");
1217
Victor Stinner6430fd52011-09-29 04:02:13 +02001218static PyObject *
Eli Bendersky4db28d32011-03-03 18:21:02 +00001219bytearray_clear(PyByteArrayObject *self)
1220{
1221 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1222 return NULL;
1223 Py_RETURN_NONE;
1224}
1225
1226PyDoc_STRVAR(copy__doc__,
1227"B.copy() -> bytearray\n\
1228\n\
1229Return a copy of B.");
1230
1231static PyObject *
1232bytearray_copy(PyByteArrayObject *self)
1233{
1234 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1235 PyByteArray_GET_SIZE(self));
1236}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001237
1238PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001239"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001240\n\
1241Like B.find() but raise ValueError when the subsection is not found.");
1242
1243static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001244bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001245{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001246 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001247 if (result == -2)
1248 return NULL;
1249 if (result == -1) {
1250 PyErr_SetString(PyExc_ValueError,
1251 "subsection not found");
1252 return NULL;
1253 }
1254 return PyLong_FromSsize_t(result);
1255}
1256
1257
1258PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001259"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001260\n\
1261Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001262such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001263arguments start and end are interpreted as in slice notation.\n\
1264\n\
1265Return -1 on failure.");
1266
1267static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001268bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001269{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001270 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001271 if (result == -2)
1272 return NULL;
1273 return PyLong_FromSsize_t(result);
1274}
1275
1276
1277PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001278"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001279\n\
1280Like B.rfind() but raise ValueError when the subsection is not found.");
1281
1282static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001283bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001284{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001285 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001286 if (result == -2)
1287 return NULL;
1288 if (result == -1) {
1289 PyErr_SetString(PyExc_ValueError,
1290 "subsection not found");
1291 return NULL;
1292 }
1293 return PyLong_FromSsize_t(result);
1294}
1295
1296
1297static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001298bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001299{
1300 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1301 if (ival == -1 && PyErr_Occurred()) {
1302 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001303 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001304 PyErr_Clear();
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001305 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001306 return -1;
1307 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1308 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001309 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001310 return pos >= 0;
1311 }
1312 if (ival < 0 || ival >= 256) {
1313 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1314 return -1;
1315 }
1316
Antoine Pitrou0010d372010-08-15 17:12:55 +00001317 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001318}
1319
1320
1321/* Matches the end (direction >= 0) or start (direction < 0) of self
1322 * against substr, using the start and end arguments. Returns
1323 * -1 on error, 0 if not found and 1 if found.
1324 */
1325Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001326_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001327 Py_ssize_t end, int direction)
1328{
1329 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1330 const char* str;
1331 Py_buffer vsubstr;
1332 int rv = 0;
1333
1334 str = PyByteArray_AS_STRING(self);
1335
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001336 if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001337 return -1;
1338
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001339 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001340
1341 if (direction < 0) {
1342 /* startswith */
1343 if (start+vsubstr.len > len) {
1344 goto done;
1345 }
1346 } else {
1347 /* endswith */
1348 if (end-start < vsubstr.len || start > len) {
1349 goto done;
1350 }
1351
1352 if (end-vsubstr.len > start)
1353 start = end - vsubstr.len;
1354 }
1355 if (end-start >= vsubstr.len)
1356 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1357
1358done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001359 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001360 return rv;
1361}
1362
1363
1364PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001365"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001366\n\
1367Return True if B starts with the specified prefix, False otherwise.\n\
1368With optional start, test B beginning at that position.\n\
1369With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001370prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001371
1372static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001373bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001374{
1375 Py_ssize_t start = 0;
1376 Py_ssize_t end = PY_SSIZE_T_MAX;
1377 PyObject *subobj;
1378 int result;
1379
Jesus Ceaac451502011-04-20 17:09:23 +02001380 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001381 return NULL;
1382 if (PyTuple_Check(subobj)) {
1383 Py_ssize_t i;
1384 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001385 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001386 PyTuple_GET_ITEM(subobj, i),
1387 start, end, -1);
1388 if (result == -1)
1389 return NULL;
1390 else if (result) {
1391 Py_RETURN_TRUE;
1392 }
1393 }
1394 Py_RETURN_FALSE;
1395 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001396 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001397 if (result == -1) {
1398 if (PyErr_ExceptionMatches(PyExc_TypeError))
1399 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1400 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001401 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001402 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001403 else
1404 return PyBool_FromLong(result);
1405}
1406
1407PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001408"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001409\n\
1410Return True if B ends with the specified suffix, False otherwise.\n\
1411With optional start, test B beginning at that position.\n\
1412With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001413suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001414
1415static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001416bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001417{
1418 Py_ssize_t start = 0;
1419 Py_ssize_t end = PY_SSIZE_T_MAX;
1420 PyObject *subobj;
1421 int result;
1422
Jesus Ceaac451502011-04-20 17:09:23 +02001423 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001424 return NULL;
1425 if (PyTuple_Check(subobj)) {
1426 Py_ssize_t i;
1427 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001428 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001429 PyTuple_GET_ITEM(subobj, i),
1430 start, end, +1);
1431 if (result == -1)
1432 return NULL;
1433 else if (result) {
1434 Py_RETURN_TRUE;
1435 }
1436 }
1437 Py_RETURN_FALSE;
1438 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001439 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001440 if (result == -1) {
1441 if (PyErr_ExceptionMatches(PyExc_TypeError))
1442 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1443 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001444 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001445 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001446 else
1447 return PyBool_FromLong(result);
1448}
1449
1450
1451PyDoc_STRVAR(translate__doc__,
1452"B.translate(table[, deletechars]) -> bytearray\n\
1453\n\
1454Return a copy of B, where all characters occurring in the\n\
1455optional argument deletechars are removed, and the remaining\n\
1456characters have been mapped through the given translation\n\
1457table, which must be a bytes object of length 256.");
1458
1459static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001460bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001461{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001462 char *input, *output;
1463 const char *table;
1464 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001465 PyObject *input_obj = (PyObject*)self;
1466 const char *output_start;
1467 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001468 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001469 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001470 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001471 Py_buffer vtable, vdel;
1472
1473 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1474 &tableobj, &delobj))
1475 return NULL;
1476
Georg Brandlccc47b62008-12-28 11:44:14 +00001477 if (tableobj == Py_None) {
1478 table = NULL;
1479 tableobj = NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001480 } else if (PyObject_GetBuffer(tableobj, &vtable, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001481 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001482 } else {
1483 if (vtable.len != 256) {
1484 PyErr_SetString(PyExc_ValueError,
1485 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001486 PyBuffer_Release(&vtable);
1487 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001488 }
1489 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001490 }
1491
1492 if (delobj != NULL) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001493 if (PyObject_GetBuffer(delobj, &vdel, PyBUF_SIMPLE) != 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001494 if (tableobj != NULL)
1495 PyBuffer_Release(&vtable);
1496 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001497 }
1498 }
1499 else {
1500 vdel.buf = NULL;
1501 vdel.len = 0;
1502 }
1503
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001504 inlen = PyByteArray_GET_SIZE(input_obj);
1505 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1506 if (result == NULL)
1507 goto done;
1508 output_start = output = PyByteArray_AsString(result);
1509 input = PyByteArray_AS_STRING(input_obj);
1510
Georg Brandlccc47b62008-12-28 11:44:14 +00001511 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001512 /* If no deletions are required, use faster code */
1513 for (i = inlen; --i >= 0; ) {
1514 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001515 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001516 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001517 goto done;
1518 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001519
1520 if (table == NULL) {
1521 for (i = 0; i < 256; i++)
1522 trans_table[i] = Py_CHARMASK(i);
1523 } else {
1524 for (i = 0; i < 256; i++)
1525 trans_table[i] = Py_CHARMASK(table[i]);
1526 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001527
1528 for (i = 0; i < vdel.len; i++)
1529 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1530
1531 for (i = inlen; --i >= 0; ) {
1532 c = Py_CHARMASK(*input++);
1533 if (trans_table[c] != -1)
1534 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1535 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001536 }
1537 /* Fix the size of the resulting string */
1538 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001539 if (PyByteArray_Resize(result, output - output_start) < 0) {
1540 Py_CLEAR(result);
1541 goto done;
1542 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001543
1544done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001545 if (tableobj != NULL)
1546 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001547 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001548 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001549 return result;
1550}
1551
1552
Georg Brandlabc38772009-04-12 15:51:51 +00001553static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001554bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001555{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001556 return _Py_bytes_maketrans(args);
Georg Brandlabc38772009-04-12 15:51:51 +00001557}
1558
1559
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001560/* find and count characters and substrings */
1561
1562#define findchar(target, target_len, c) \
1563 ((char *)memchr((const void *)(target), c, target_len))
1564
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001565
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001566/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001567Py_LOCAL(PyByteArrayObject *)
1568return_self(PyByteArrayObject *self)
1569{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001570 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001571 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1572 PyByteArray_AS_STRING(self),
1573 PyByteArray_GET_SIZE(self));
1574}
1575
1576Py_LOCAL_INLINE(Py_ssize_t)
1577countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1578{
1579 Py_ssize_t count=0;
1580 const char *start=target;
1581 const char *end=target+target_len;
1582
1583 while ( (start=findchar(start, end-start, c)) != NULL ) {
1584 count++;
1585 if (count >= maxcount)
1586 break;
1587 start += 1;
1588 }
1589 return count;
1590}
1591
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001592
1593/* Algorithms for different cases of string replacement */
1594
1595/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1596Py_LOCAL(PyByteArrayObject *)
1597replace_interleave(PyByteArrayObject *self,
1598 const char *to_s, Py_ssize_t to_len,
1599 Py_ssize_t maxcount)
1600{
1601 char *self_s, *result_s;
1602 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001603 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001604 PyByteArrayObject *result;
1605
1606 self_len = PyByteArray_GET_SIZE(self);
1607
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001608 /* 1 at the end plus 1 after every character;
1609 count = min(maxcount, self_len + 1) */
1610 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001611 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001612 else
1613 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1614 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001615
1616 /* Check for overflow */
1617 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001618 assert(count > 0);
1619 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001620 PyErr_SetString(PyExc_OverflowError,
1621 "replace string is too long");
1622 return NULL;
1623 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001624 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001625
1626 if (! (result = (PyByteArrayObject *)
1627 PyByteArray_FromStringAndSize(NULL, result_len)) )
1628 return NULL;
1629
1630 self_s = PyByteArray_AS_STRING(self);
1631 result_s = PyByteArray_AS_STRING(result);
1632
1633 /* TODO: special case single character, which doesn't need memcpy */
1634
1635 /* Lay the first one down (guaranteed this will occur) */
1636 Py_MEMCPY(result_s, to_s, to_len);
1637 result_s += to_len;
1638 count -= 1;
1639
1640 for (i=0; i<count; i++) {
1641 *result_s++ = *self_s++;
1642 Py_MEMCPY(result_s, to_s, to_len);
1643 result_s += to_len;
1644 }
1645
1646 /* Copy the rest of the original string */
1647 Py_MEMCPY(result_s, self_s, self_len-i);
1648
1649 return result;
1650}
1651
1652/* Special case for deleting a single character */
1653/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1654Py_LOCAL(PyByteArrayObject *)
1655replace_delete_single_character(PyByteArrayObject *self,
1656 char from_c, Py_ssize_t maxcount)
1657{
1658 char *self_s, *result_s;
1659 char *start, *next, *end;
1660 Py_ssize_t self_len, result_len;
1661 Py_ssize_t count;
1662 PyByteArrayObject *result;
1663
1664 self_len = PyByteArray_GET_SIZE(self);
1665 self_s = PyByteArray_AS_STRING(self);
1666
1667 count = countchar(self_s, self_len, from_c, maxcount);
1668 if (count == 0) {
1669 return return_self(self);
1670 }
1671
1672 result_len = self_len - count; /* from_len == 1 */
1673 assert(result_len>=0);
1674
1675 if ( (result = (PyByteArrayObject *)
1676 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1677 return NULL;
1678 result_s = PyByteArray_AS_STRING(result);
1679
1680 start = self_s;
1681 end = self_s + self_len;
1682 while (count-- > 0) {
1683 next = findchar(start, end-start, from_c);
1684 if (next == NULL)
1685 break;
1686 Py_MEMCPY(result_s, start, next-start);
1687 result_s += (next-start);
1688 start = next+1;
1689 }
1690 Py_MEMCPY(result_s, start, end-start);
1691
1692 return result;
1693}
1694
1695/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1696
1697Py_LOCAL(PyByteArrayObject *)
1698replace_delete_substring(PyByteArrayObject *self,
1699 const char *from_s, Py_ssize_t from_len,
1700 Py_ssize_t maxcount)
1701{
1702 char *self_s, *result_s;
1703 char *start, *next, *end;
1704 Py_ssize_t self_len, result_len;
1705 Py_ssize_t count, offset;
1706 PyByteArrayObject *result;
1707
1708 self_len = PyByteArray_GET_SIZE(self);
1709 self_s = PyByteArray_AS_STRING(self);
1710
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001711 count = stringlib_count(self_s, self_len,
1712 from_s, from_len,
1713 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001714
1715 if (count == 0) {
1716 /* no matches */
1717 return return_self(self);
1718 }
1719
1720 result_len = self_len - (count * from_len);
1721 assert (result_len>=0);
1722
1723 if ( (result = (PyByteArrayObject *)
1724 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1725 return NULL;
1726
1727 result_s = PyByteArray_AS_STRING(result);
1728
1729 start = self_s;
1730 end = self_s + self_len;
1731 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001732 offset = stringlib_find(start, end-start,
1733 from_s, from_len,
1734 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001735 if (offset == -1)
1736 break;
1737 next = start + offset;
1738
1739 Py_MEMCPY(result_s, start, next-start);
1740
1741 result_s += (next-start);
1742 start = next+from_len;
1743 }
1744 Py_MEMCPY(result_s, start, end-start);
1745 return result;
1746}
1747
1748/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1749Py_LOCAL(PyByteArrayObject *)
1750replace_single_character_in_place(PyByteArrayObject *self,
1751 char from_c, char to_c,
1752 Py_ssize_t maxcount)
1753{
Antoine Pitroud1188562010-06-09 16:38:55 +00001754 char *self_s, *result_s, *start, *end, *next;
1755 Py_ssize_t self_len;
1756 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001757
Antoine Pitroud1188562010-06-09 16:38:55 +00001758 /* The result string will be the same size */
1759 self_s = PyByteArray_AS_STRING(self);
1760 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001761
Antoine Pitroud1188562010-06-09 16:38:55 +00001762 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001763
Antoine Pitroud1188562010-06-09 16:38:55 +00001764 if (next == NULL) {
1765 /* No matches; return the original bytes */
1766 return return_self(self);
1767 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001768
Antoine Pitroud1188562010-06-09 16:38:55 +00001769 /* Need to make a new bytes */
1770 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1771 if (result == NULL)
1772 return NULL;
1773 result_s = PyByteArray_AS_STRING(result);
1774 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001775
Antoine Pitroud1188562010-06-09 16:38:55 +00001776 /* change everything in-place, starting with this one */
1777 start = result_s + (next-self_s);
1778 *start = to_c;
1779 start++;
1780 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001781
Antoine Pitroud1188562010-06-09 16:38:55 +00001782 while (--maxcount > 0) {
1783 next = findchar(start, end-start, from_c);
1784 if (next == NULL)
1785 break;
1786 *next = to_c;
1787 start = next+1;
1788 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001789
Antoine Pitroud1188562010-06-09 16:38:55 +00001790 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001791}
1792
1793/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1794Py_LOCAL(PyByteArrayObject *)
1795replace_substring_in_place(PyByteArrayObject *self,
1796 const char *from_s, Py_ssize_t from_len,
1797 const char *to_s, Py_ssize_t to_len,
1798 Py_ssize_t maxcount)
1799{
1800 char *result_s, *start, *end;
1801 char *self_s;
1802 Py_ssize_t self_len, offset;
1803 PyByteArrayObject *result;
1804
1805 /* The result bytes will be the same size */
1806
1807 self_s = PyByteArray_AS_STRING(self);
1808 self_len = PyByteArray_GET_SIZE(self);
1809
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001810 offset = stringlib_find(self_s, self_len,
1811 from_s, from_len,
1812 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001813 if (offset == -1) {
1814 /* No matches; return the original bytes */
1815 return return_self(self);
1816 }
1817
1818 /* Need to make a new bytes */
1819 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1820 if (result == NULL)
1821 return NULL;
1822 result_s = PyByteArray_AS_STRING(result);
1823 Py_MEMCPY(result_s, self_s, self_len);
1824
1825 /* change everything in-place, starting with this one */
1826 start = result_s + offset;
1827 Py_MEMCPY(start, to_s, from_len);
1828 start += from_len;
1829 end = result_s + self_len;
1830
1831 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001832 offset = stringlib_find(start, end-start,
1833 from_s, from_len,
1834 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001835 if (offset==-1)
1836 break;
1837 Py_MEMCPY(start+offset, to_s, from_len);
1838 start += offset+from_len;
1839 }
1840
1841 return result;
1842}
1843
1844/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1845Py_LOCAL(PyByteArrayObject *)
1846replace_single_character(PyByteArrayObject *self,
1847 char from_c,
1848 const char *to_s, Py_ssize_t to_len,
1849 Py_ssize_t maxcount)
1850{
1851 char *self_s, *result_s;
1852 char *start, *next, *end;
1853 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001854 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001855 PyByteArrayObject *result;
1856
1857 self_s = PyByteArray_AS_STRING(self);
1858 self_len = PyByteArray_GET_SIZE(self);
1859
1860 count = countchar(self_s, self_len, from_c, maxcount);
1861 if (count == 0) {
1862 /* no matches, return unchanged */
1863 return return_self(self);
1864 }
1865
1866 /* use the difference between current and new, hence the "-1" */
1867 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001868 assert(count > 0);
1869 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001870 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1871 return NULL;
1872 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001873 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001874
1875 if ( (result = (PyByteArrayObject *)
1876 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1877 return NULL;
1878 result_s = PyByteArray_AS_STRING(result);
1879
1880 start = self_s;
1881 end = self_s + self_len;
1882 while (count-- > 0) {
1883 next = findchar(start, end-start, from_c);
1884 if (next == NULL)
1885 break;
1886
1887 if (next == start) {
1888 /* replace with the 'to' */
1889 Py_MEMCPY(result_s, to_s, to_len);
1890 result_s += to_len;
1891 start += 1;
1892 } else {
1893 /* copy the unchanged old then the 'to' */
1894 Py_MEMCPY(result_s, start, next-start);
1895 result_s += (next-start);
1896 Py_MEMCPY(result_s, to_s, to_len);
1897 result_s += to_len;
1898 start = next+1;
1899 }
1900 }
1901 /* Copy the remainder of the remaining bytes */
1902 Py_MEMCPY(result_s, start, end-start);
1903
1904 return result;
1905}
1906
1907/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1908Py_LOCAL(PyByteArrayObject *)
1909replace_substring(PyByteArrayObject *self,
1910 const char *from_s, Py_ssize_t from_len,
1911 const char *to_s, Py_ssize_t to_len,
1912 Py_ssize_t maxcount)
1913{
1914 char *self_s, *result_s;
1915 char *start, *next, *end;
1916 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001917 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001918 PyByteArrayObject *result;
1919
1920 self_s = PyByteArray_AS_STRING(self);
1921 self_len = PyByteArray_GET_SIZE(self);
1922
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001923 count = stringlib_count(self_s, self_len,
1924 from_s, from_len,
1925 maxcount);
1926
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001927 if (count == 0) {
1928 /* no matches, return unchanged */
1929 return return_self(self);
1930 }
1931
1932 /* Check for overflow */
1933 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001934 assert(count > 0);
1935 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001936 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1937 return NULL;
1938 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001939 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001940
1941 if ( (result = (PyByteArrayObject *)
1942 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1943 return NULL;
1944 result_s = PyByteArray_AS_STRING(result);
1945
1946 start = self_s;
1947 end = self_s + self_len;
1948 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001949 offset = stringlib_find(start, end-start,
1950 from_s, from_len,
1951 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001952 if (offset == -1)
1953 break;
1954 next = start+offset;
1955 if (next == start) {
1956 /* replace with the 'to' */
1957 Py_MEMCPY(result_s, to_s, to_len);
1958 result_s += to_len;
1959 start += from_len;
1960 } else {
1961 /* copy the unchanged old then the 'to' */
1962 Py_MEMCPY(result_s, start, next-start);
1963 result_s += (next-start);
1964 Py_MEMCPY(result_s, to_s, to_len);
1965 result_s += to_len;
1966 start = next+from_len;
1967 }
1968 }
1969 /* Copy the remainder of the remaining bytes */
1970 Py_MEMCPY(result_s, start, end-start);
1971
1972 return result;
1973}
1974
1975
1976Py_LOCAL(PyByteArrayObject *)
1977replace(PyByteArrayObject *self,
1978 const char *from_s, Py_ssize_t from_len,
1979 const char *to_s, Py_ssize_t to_len,
1980 Py_ssize_t maxcount)
1981{
1982 if (maxcount < 0) {
1983 maxcount = PY_SSIZE_T_MAX;
1984 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1985 /* nothing to do; return the original bytes */
1986 return return_self(self);
1987 }
1988
1989 if (maxcount == 0 ||
1990 (from_len == 0 && to_len == 0)) {
1991 /* nothing to do; return the original bytes */
1992 return return_self(self);
1993 }
1994
1995 /* Handle zero-length special cases */
1996
1997 if (from_len == 0) {
1998 /* insert the 'to' bytes everywhere. */
1999 /* >>> "Python".replace("", ".") */
2000 /* '.P.y.t.h.o.n.' */
2001 return replace_interleave(self, to_s, to_len, maxcount);
2002 }
2003
2004 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2005 /* point for an empty self bytes to generate a non-empty bytes */
2006 /* Special case so the remaining code always gets a non-empty bytes */
2007 if (PyByteArray_GET_SIZE(self) == 0) {
2008 return return_self(self);
2009 }
2010
2011 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002012 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002013 if (from_len == 1) {
2014 return replace_delete_single_character(
2015 self, from_s[0], maxcount);
2016 } else {
2017 return replace_delete_substring(self, from_s, from_len, maxcount);
2018 }
2019 }
2020
2021 /* Handle special case where both bytes have the same length */
2022
2023 if (from_len == to_len) {
2024 if (from_len == 1) {
2025 return replace_single_character_in_place(
2026 self,
2027 from_s[0],
2028 to_s[0],
2029 maxcount);
2030 } else {
2031 return replace_substring_in_place(
2032 self, from_s, from_len, to_s, to_len, maxcount);
2033 }
2034 }
2035
2036 /* Otherwise use the more generic algorithms */
2037 if (from_len == 1) {
2038 return replace_single_character(self, from_s[0],
2039 to_s, to_len, maxcount);
2040 } else {
2041 /* len('from')>=2, len('to')>=1 */
2042 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2043 }
2044}
2045
2046
2047PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002048"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002049\n\
2050Return a copy of B with all occurrences of subsection\n\
2051old replaced by new. If the optional argument count is\n\
2052given, only the first count occurrences are replaced.");
2053
2054static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002055bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002056{
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002057 PyObject *res;
2058 Py_buffer old = {NULL, NULL};
2059 Py_buffer new = {NULL, NULL};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002060 Py_ssize_t count = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002061
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002062 if (!PyArg_ParseTuple(args, "y*y*|n:replace", &old, &new, &count))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002063 return NULL;
2064
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002065 res = (PyObject *)replace((PyByteArrayObject *) self,
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002066 (const char *)old.buf, old.len,
2067 (const char *)new.buf, new.len, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002068
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002069 PyBuffer_Release(&old);
2070 PyBuffer_Release(&new);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002071 return res;
2072}
2073
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002074PyDoc_STRVAR(split__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002075"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002076\n\
2077Return a list of the sections in B, using sep as the delimiter.\n\
2078If sep is not given, B is split on ASCII whitespace characters\n\
2079(space, tab, return, newline, formfeed, vertical tab).\n\
2080If maxsplit is given, at most maxsplit splits are done.");
2081
2082static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002083bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002084{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002085 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002086 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2087 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002088 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002089 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002090 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002091
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002092 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
2093 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002094 return NULL;
2095 if (maxsplit < 0)
2096 maxsplit = PY_SSIZE_T_MAX;
2097
2098 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002099 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002100
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002101 if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002102 return NULL;
2103 sub = vsub.buf;
2104 n = vsub.len;
2105
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002106 list = stringlib_split(
2107 (PyObject*) self, s, len, sub, n, maxsplit
2108 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002109 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002110 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002111}
2112
2113PyDoc_STRVAR(partition__doc__,
2114"B.partition(sep) -> (head, sep, tail)\n\
2115\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002116Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002117the separator itself, and the part after it. If the separator is not\n\
2118found, returns B and two empty bytearray objects.");
2119
2120static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002121bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002122{
2123 PyObject *bytesep, *result;
2124
2125 bytesep = PyByteArray_FromObject(sep_obj);
2126 if (! bytesep)
2127 return NULL;
2128
2129 result = stringlib_partition(
2130 (PyObject*) self,
2131 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2132 bytesep,
2133 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2134 );
2135
2136 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002137 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002138}
2139
2140PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002141"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002142\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002143Search for the separator sep in B, starting at the end of B,\n\
2144and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002145part after it. If the separator is not found, returns two empty\n\
2146bytearray objects and B.");
2147
2148static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002149bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002150{
2151 PyObject *bytesep, *result;
2152
2153 bytesep = PyByteArray_FromObject(sep_obj);
2154 if (! bytesep)
2155 return NULL;
2156
2157 result = stringlib_rpartition(
2158 (PyObject*) self,
2159 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2160 bytesep,
2161 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2162 );
2163
2164 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002165 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002166}
2167
2168PyDoc_STRVAR(rsplit__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002169"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002170\n\
2171Return a list of the sections in B, using sep as the delimiter,\n\
2172starting at the end of B and working to the front.\n\
2173If sep is not given, B is split on ASCII whitespace characters\n\
2174(space, tab, return, newline, formfeed, vertical tab).\n\
2175If maxsplit is given, at most maxsplit splits are done.");
2176
2177static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002178bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002179{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002180 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002181 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2182 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002183 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002184 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002185 Py_buffer vsub;
2186
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002187 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit",
2188 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002189 return NULL;
2190 if (maxsplit < 0)
2191 maxsplit = PY_SSIZE_T_MAX;
2192
2193 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002194 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002195
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002196 if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002197 return NULL;
2198 sub = vsub.buf;
2199 n = vsub.len;
2200
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002201 list = stringlib_rsplit(
2202 (PyObject*) self, s, len, sub, n, maxsplit
2203 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002204 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002205 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002206}
2207
2208PyDoc_STRVAR(reverse__doc__,
2209"B.reverse() -> None\n\
2210\n\
2211Reverse the order of the values in B in place.");
2212static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002213bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002214{
2215 char swap, *head, *tail;
2216 Py_ssize_t i, j, n = Py_SIZE(self);
2217
2218 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002219 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002220 tail = head + n - 1;
2221 for (i = 0; i < j; i++) {
2222 swap = *head;
2223 *head++ = *tail;
2224 *tail-- = swap;
2225 }
2226
2227 Py_RETURN_NONE;
2228}
2229
2230PyDoc_STRVAR(insert__doc__,
2231"B.insert(index, int) -> None\n\
2232\n\
2233Insert a single item into the bytearray before the given index.");
2234static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002235bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002236{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002237 PyObject *value;
2238 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002239 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002240 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002241
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002242 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002243 return NULL;
2244
2245 if (n == PY_SSIZE_T_MAX) {
2246 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002247 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002248 return NULL;
2249 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002250 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002251 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002252 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2253 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002254 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002255
2256 if (where < 0) {
2257 where += n;
2258 if (where < 0)
2259 where = 0;
2260 }
2261 if (where > n)
2262 where = n;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002263 memmove(buf + where + 1, buf + where, n - where);
2264 buf[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002265
2266 Py_RETURN_NONE;
2267}
2268
2269PyDoc_STRVAR(append__doc__,
2270"B.append(int) -> None\n\
2271\n\
2272Append a single item to the end of B.");
2273static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002274bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002275{
2276 int value;
2277 Py_ssize_t n = Py_SIZE(self);
2278
2279 if (! _getbytevalue(arg, &value))
2280 return NULL;
2281 if (n == PY_SSIZE_T_MAX) {
2282 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002283 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002284 return NULL;
2285 }
2286 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2287 return NULL;
2288
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002289 PyByteArray_AS_STRING(self)[n] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002290
2291 Py_RETURN_NONE;
2292}
2293
2294PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002295"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002296\n\
2297Append all the elements from the iterator or sequence to the\n\
2298end of B.");
2299static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002300bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002301{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002302 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002303 Py_ssize_t buf_size = 0, len = 0;
2304 int value;
2305 char *buf;
2306
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002307 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002308 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002309 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002310 return NULL;
2311
2312 Py_RETURN_NONE;
2313 }
2314
2315 it = PyObject_GetIter(arg);
2316 if (it == NULL)
2317 return NULL;
2318
Ezio Melotti42da6632011-03-15 05:18:48 +02002319 /* Try to determine the length of the argument. 32 is arbitrary. */
Armin Ronacheraa9a79d2012-10-06 14:03:24 +02002320 buf_size = PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002321 if (buf_size == -1) {
2322 Py_DECREF(it);
2323 return NULL;
2324 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002325
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002326 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002327 if (bytearray_obj == NULL) {
2328 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002329 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002330 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002331 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002332
2333 while ((item = PyIter_Next(it)) != NULL) {
2334 if (! _getbytevalue(item, &value)) {
2335 Py_DECREF(item);
2336 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002337 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002338 return NULL;
2339 }
2340 buf[len++] = value;
2341 Py_DECREF(item);
2342
2343 if (len >= buf_size) {
2344 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002345 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002346 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002347 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002348 return NULL;
2349 }
2350 /* Recompute the `buf' pointer, since the resizing operation may
2351 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002352 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002353 }
2354 }
2355 Py_DECREF(it);
2356
2357 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002358 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2359 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002360 return NULL;
2361 }
2362
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002363 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2364 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002365 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002366 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002367 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002368
2369 Py_RETURN_NONE;
2370}
2371
2372PyDoc_STRVAR(pop__doc__,
2373"B.pop([index]) -> int\n\
2374\n\
2375Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002376argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002377static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002378bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002379{
2380 int value;
2381 Py_ssize_t where = -1, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002382 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002383
2384 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2385 return NULL;
2386
2387 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002388 PyErr_SetString(PyExc_IndexError,
2389 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002390 return NULL;
2391 }
2392 if (where < 0)
2393 where += Py_SIZE(self);
2394 if (where < 0 || where >= Py_SIZE(self)) {
2395 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2396 return NULL;
2397 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002398 if (!_canresize(self))
2399 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002400
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002401 buf = PyByteArray_AS_STRING(self);
2402 value = buf[where];
2403 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002404 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2405 return NULL;
2406
Mark Dickinson54a3db92009-09-06 10:19:23 +00002407 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002408}
2409
2410PyDoc_STRVAR(remove__doc__,
2411"B.remove(int) -> None\n\
2412\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002413Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002414static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002415bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002416{
2417 int value;
2418 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002419 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002420
2421 if (! _getbytevalue(arg, &value))
2422 return NULL;
2423
2424 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002425 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002426 break;
2427 }
2428 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002429 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002430 return NULL;
2431 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002432 if (!_canresize(self))
2433 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002434
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002435 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002436 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2437 return NULL;
2438
2439 Py_RETURN_NONE;
2440}
2441
2442/* XXX These two helpers could be optimized if argsize == 1 */
2443
2444static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002445lstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002446 void *argptr, Py_ssize_t argsize)
2447{
2448 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002449 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002450 i++;
2451 return i;
2452}
2453
2454static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002455rstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002456 void *argptr, Py_ssize_t argsize)
2457{
2458 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002459 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002460 i--;
2461 return i + 1;
2462}
2463
2464PyDoc_STRVAR(strip__doc__,
2465"B.strip([bytes]) -> bytearray\n\
2466\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002467Strip leading and trailing bytes contained in the argument\n\
2468and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002469If the argument is omitted, strip ASCII whitespace.");
2470static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002471bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002472{
2473 Py_ssize_t left, right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002474 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002475 PyObject *arg = Py_None;
2476 Py_buffer varg;
2477 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2478 return NULL;
2479 if (arg == Py_None) {
2480 argptr = "\t\n\r\f\v ";
2481 argsize = 6;
2482 }
2483 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002484 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002485 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002486 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002487 argsize = varg.len;
2488 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002489 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002490 mysize = Py_SIZE(self);
2491 left = lstrip_helper(myptr, mysize, argptr, argsize);
2492 if (left == mysize)
2493 right = left;
2494 else
2495 right = rstrip_helper(myptr, mysize, argptr, argsize);
2496 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002497 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002498 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002499}
2500
2501PyDoc_STRVAR(lstrip__doc__,
2502"B.lstrip([bytes]) -> bytearray\n\
2503\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002504Strip leading bytes contained in the argument\n\
2505and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002506If the argument is omitted, strip leading ASCII whitespace.");
2507static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002508bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002509{
2510 Py_ssize_t left, right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002511 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002512 PyObject *arg = Py_None;
2513 Py_buffer varg;
2514 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2515 return NULL;
2516 if (arg == Py_None) {
2517 argptr = "\t\n\r\f\v ";
2518 argsize = 6;
2519 }
2520 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002521 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002522 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002523 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002524 argsize = varg.len;
2525 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002526 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002527 mysize = Py_SIZE(self);
2528 left = lstrip_helper(myptr, mysize, argptr, argsize);
2529 right = mysize;
2530 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002531 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002532 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002533}
2534
2535PyDoc_STRVAR(rstrip__doc__,
2536"B.rstrip([bytes]) -> bytearray\n\
2537\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002538Strip trailing bytes contained in the argument\n\
2539and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002540If the argument is omitted, strip trailing ASCII whitespace.");
2541static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002542bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002543{
Brett Cannonb94767f2011-02-22 20:15:44 +00002544 Py_ssize_t right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002545 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002546 PyObject *arg = Py_None;
2547 Py_buffer varg;
2548 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2549 return NULL;
2550 if (arg == Py_None) {
2551 argptr = "\t\n\r\f\v ";
2552 argsize = 6;
2553 }
2554 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002555 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002556 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002557 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002558 argsize = varg.len;
2559 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002560 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002561 mysize = Py_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002562 right = rstrip_helper(myptr, mysize, argptr, argsize);
2563 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002564 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002565 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002566}
2567
2568PyDoc_STRVAR(decode_doc,
Victor Stinnerc911bbf2010-11-07 19:04:46 +00002569"B.decode(encoding='utf-8', errors='strict') -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002570\n\
Victor Stinnere14e2122010-11-07 18:41:46 +00002571Decode B using the codec registered for encoding. Default encoding\n\
2572is 'utf-8'. errors may be given to set a different error\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002573handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2574a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2575as well as any other name registered with codecs.register_error that is\n\
2576able to handle UnicodeDecodeErrors.");
2577
2578static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002579bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002580{
2581 const char *encoding = NULL;
2582 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002583 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002584
Benjamin Peterson308d6372009-09-18 21:42:35 +00002585 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002586 return NULL;
2587 if (encoding == NULL)
2588 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002589 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002590}
2591
2592PyDoc_STRVAR(alloc_doc,
2593"B.__alloc__() -> int\n\
2594\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002595Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002596
2597static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002598bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002599{
2600 return PyLong_FromSsize_t(self->ob_alloc);
2601}
2602
2603PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002604"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002605\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002606Concatenate any number of bytes/bytearray objects, with B\n\
2607in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002608
2609static PyObject *
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002610bytearray_join(PyObject *self, PyObject *iterable)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002611{
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002612 return stringlib_bytes_join(self, iterable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002613}
2614
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002615PyDoc_STRVAR(splitlines__doc__,
2616"B.splitlines([keepends]) -> list of lines\n\
2617\n\
2618Return a list of the lines in B, breaking at line boundaries.\n\
2619Line breaks are not included in the resulting list unless keepends\n\
2620is given and true.");
2621
2622static PyObject*
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002623bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002624{
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002625 static char *kwlist[] = {"keepends", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002626 int keepends = 0;
2627
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002628 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines",
2629 kwlist, &keepends))
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002630 return NULL;
2631
2632 return stringlib_splitlines(
2633 (PyObject*) self, PyByteArray_AS_STRING(self),
2634 PyByteArray_GET_SIZE(self), keepends
2635 );
2636}
2637
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002638PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002639"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002640\n\
2641Create a bytearray object from a string of hexadecimal numbers.\n\
2642Spaces between two numbers are accepted.\n\
2643Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2644
2645static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002646hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002647{
2648 if (c >= 128)
2649 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002650 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002651 return c - '0';
2652 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002653 if (Py_ISUPPER(c))
2654 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002655 if (c >= 'a' && c <= 'f')
2656 return c - 'a' + 10;
2657 }
2658 return -1;
2659}
2660
2661static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002662bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002663{
2664 PyObject *newbytes, *hexobj;
2665 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002666 Py_ssize_t hexlen, byteslen, i, j;
2667 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002668 void *data;
2669 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002670
2671 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2672 return NULL;
2673 assert(PyUnicode_Check(hexobj));
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002674 if (PyUnicode_READY(hexobj))
2675 return NULL;
2676 kind = PyUnicode_KIND(hexobj);
2677 data = PyUnicode_DATA(hexobj);
2678 hexlen = PyUnicode_GET_LENGTH(hexobj);
2679
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002680 byteslen = hexlen/2; /* This overestimates if there are spaces */
2681 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2682 if (!newbytes)
2683 return NULL;
2684 buf = PyByteArray_AS_STRING(newbytes);
2685 for (i = j = 0; i < hexlen; i += 2) {
2686 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002687 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002688 i++;
2689 if (i >= hexlen)
2690 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002691 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2692 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002693 if (top == -1 || bot == -1) {
2694 PyErr_Format(PyExc_ValueError,
2695 "non-hexadecimal number found in "
2696 "fromhex() arg at position %zd", i);
2697 goto error;
2698 }
2699 buf[j++] = (top << 4) + bot;
2700 }
2701 if (PyByteArray_Resize(newbytes, j) < 0)
2702 goto error;
2703 return newbytes;
2704
2705 error:
2706 Py_DECREF(newbytes);
2707 return NULL;
2708}
2709
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002710
2711static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002712_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002713{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002714 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002715 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002716 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002717
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002718 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002719 if (dict == NULL) {
2720 PyErr_Clear();
2721 dict = Py_None;
2722 Py_INCREF(dict);
2723 }
2724
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002725 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002726 if (proto < 3) {
2727 /* use str based reduction for backwards compatibility with Python 2.x */
2728 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002729 if (Py_SIZE(self))
2730 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002731 else
2732 latin1 = PyUnicode_FromString("");
2733 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2734 }
2735 else {
2736 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002737 if (Py_SIZE(self)) {
2738 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002739 }
2740 else {
2741 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2742 }
2743 }
2744}
2745
2746PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2747
2748static PyObject *
2749bytearray_reduce(PyByteArrayObject *self)
2750{
2751 return _common_reduce(self, 2);
2752}
2753
2754PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling.");
2755
2756static PyObject *
2757bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
2758{
2759 int proto = 0;
2760
2761 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
2762 return NULL;
2763
2764 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002765}
2766
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002767PyDoc_STRVAR(sizeof_doc,
2768"B.__sizeof__() -> int\n\
2769 \n\
2770Returns the size of B in memory, in bytes");
2771static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002772bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002773{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002774 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002775
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002776 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2777 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002778}
2779
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002780static PySequenceMethods bytearray_as_sequence = {
2781 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002782 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002783 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2784 (ssizeargfunc)bytearray_getitem, /* sq_item */
2785 0, /* sq_slice */
2786 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2787 0, /* sq_ass_slice */
2788 (objobjproc)bytearray_contains, /* sq_contains */
2789 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2790 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002791};
2792
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002793static PyMappingMethods bytearray_as_mapping = {
2794 (lenfunc)bytearray_length,
2795 (binaryfunc)bytearray_subscript,
2796 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002797};
2798
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002799static PyBufferProcs bytearray_as_buffer = {
2800 (getbufferproc)bytearray_getbuffer,
2801 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002802};
2803
2804static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002805bytearray_methods[] = {
2806 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2807 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002808 {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002809 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2810 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002811 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2812 _Py_capitalize__doc__},
2813 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00002814 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__},
2815 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002816 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002817 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002818 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Ezio Melotti745d54d2013-11-16 19:10:57 +02002819 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002820 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002821 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2822 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2823 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002824 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002825 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2826 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002827 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2828 _Py_isalnum__doc__},
2829 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2830 _Py_isalpha__doc__},
2831 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2832 _Py_isdigit__doc__},
2833 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2834 _Py_islower__doc__},
2835 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2836 _Py_isspace__doc__},
2837 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2838 _Py_istitle__doc__},
2839 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2840 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002841 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002842 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2843 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002844 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2845 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002846 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002847 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2848 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2849 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2850 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2851 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2852 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2853 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002854 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002855 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002856 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002857 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002858 {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__},
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002859 {"splitlines", (PyCFunction)bytearray_splitlines,
2860 METH_VARARGS | METH_KEYWORDS, splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002861 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002862 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002863 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002864 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2865 _Py_swapcase__doc__},
2866 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002867 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002868 translate__doc__},
2869 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2870 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2871 {NULL}
2872};
2873
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002874PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002875"bytearray(iterable_of_ints) -> bytearray\n\
2876bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002877bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2878bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2879bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002880\n\
2881Construct an mutable bytearray object from:\n\
2882 - an iterable yielding integers in range(256)\n\
2883 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002884 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002885 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002886 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002887
2888
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002889static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002890
2891PyTypeObject PyByteArray_Type = {
2892 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2893 "bytearray",
2894 sizeof(PyByteArrayObject),
2895 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002896 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002897 0, /* tp_print */
2898 0, /* tp_getattr */
2899 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002900 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002901 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002902 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002903 &bytearray_as_sequence, /* tp_as_sequence */
2904 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002905 0, /* tp_hash */
2906 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002907 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002908 PyObject_GenericGetAttr, /* tp_getattro */
2909 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002910 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002911 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002912 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002913 0, /* tp_traverse */
2914 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002915 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002916 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002917 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002918 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002919 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002920 0, /* tp_members */
2921 0, /* tp_getset */
2922 0, /* tp_base */
2923 0, /* tp_dict */
2924 0, /* tp_descr_get */
2925 0, /* tp_descr_set */
2926 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002927 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002928 PyType_GenericAlloc, /* tp_alloc */
2929 PyType_GenericNew, /* tp_new */
2930 PyObject_Del, /* tp_free */
2931};
2932
2933/*********************** Bytes Iterator ****************************/
2934
2935typedef struct {
2936 PyObject_HEAD
2937 Py_ssize_t it_index;
2938 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2939} bytesiterobject;
2940
2941static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002942bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002943{
2944 _PyObject_GC_UNTRACK(it);
2945 Py_XDECREF(it->it_seq);
2946 PyObject_GC_Del(it);
2947}
2948
2949static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002950bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002951{
2952 Py_VISIT(it->it_seq);
2953 return 0;
2954}
2955
2956static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002957bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002958{
2959 PyByteArrayObject *seq;
2960 PyObject *item;
2961
2962 assert(it != NULL);
2963 seq = it->it_seq;
2964 if (seq == NULL)
2965 return NULL;
2966 assert(PyByteArray_Check(seq));
2967
2968 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2969 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002970 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002971 if (item != NULL)
2972 ++it->it_index;
2973 return item;
2974 }
2975
2976 Py_DECREF(seq);
2977 it->it_seq = NULL;
2978 return NULL;
2979}
2980
2981static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002982bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002983{
2984 Py_ssize_t len = 0;
2985 if (it->it_seq)
2986 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2987 return PyLong_FromSsize_t(len);
2988}
2989
2990PyDoc_STRVAR(length_hint_doc,
2991 "Private method returning an estimate of len(list(it)).");
2992
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002993static PyObject *
2994bytearrayiter_reduce(bytesiterobject *it)
2995{
2996 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02002997 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002998 it->it_seq, it->it_index);
2999 } else {
3000 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
3001 if (u == NULL)
3002 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02003003 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003004 }
3005}
3006
3007static PyObject *
3008bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3009{
3010 Py_ssize_t index = PyLong_AsSsize_t(state);
3011 if (index == -1 && PyErr_Occurred())
3012 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +00003013 if (it->it_seq != NULL) {
3014 if (index < 0)
3015 index = 0;
3016 else if (index > PyByteArray_GET_SIZE(it->it_seq))
3017 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
3018 it->it_index = index;
3019 }
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003020 Py_RETURN_NONE;
3021}
3022
3023PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3024
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003025static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003026 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003027 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003028 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
3029 reduce_doc},
3030 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3031 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003032 {NULL, NULL} /* sentinel */
3033};
3034
3035PyTypeObject PyByteArrayIter_Type = {
3036 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3037 "bytearray_iterator", /* tp_name */
3038 sizeof(bytesiterobject), /* tp_basicsize */
3039 0, /* tp_itemsize */
3040 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003041 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003042 0, /* tp_print */
3043 0, /* tp_getattr */
3044 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003045 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003046 0, /* tp_repr */
3047 0, /* tp_as_number */
3048 0, /* tp_as_sequence */
3049 0, /* tp_as_mapping */
3050 0, /* tp_hash */
3051 0, /* tp_call */
3052 0, /* tp_str */
3053 PyObject_GenericGetAttr, /* tp_getattro */
3054 0, /* tp_setattro */
3055 0, /* tp_as_buffer */
3056 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3057 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003058 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003059 0, /* tp_clear */
3060 0, /* tp_richcompare */
3061 0, /* tp_weaklistoffset */
3062 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003063 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3064 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003065 0,
3066};
3067
3068static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003069bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003070{
3071 bytesiterobject *it;
3072
3073 if (!PyByteArray_Check(seq)) {
3074 PyErr_BadInternalCall();
3075 return NULL;
3076 }
3077 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3078 if (it == NULL)
3079 return NULL;
3080 it->it_index = 0;
3081 Py_INCREF(seq);
3082 it->it_seq = (PyByteArrayObject *)seq;
3083 _PyObject_GC_TRACK(it);
3084 return (PyObject *)it;
3085}