blob: 8629ab7772e396e84089039075582c5b2dbb6031 [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 */
857 if (Py_SIZE(self) < self->ob_alloc)
858 Py_SIZE(self)++;
859 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
860 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200861 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000862 }
863
864 /* Clean up and return success */
865 Py_DECREF(it);
866 return 0;
867
868 error:
869 /* Error handling when it != NULL */
870 Py_DECREF(it);
871 return -1;
872}
873
874/* Mostly copied from string_repr, but without the
875 "smart quote" functionality. */
876static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000877bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000878{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000879 const char *quote_prefix = "bytearray(b";
880 const char *quote_postfix = ")";
881 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200882 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000883 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000884 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200885 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200886 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200887 char c;
888 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200889 int quote;
890 char *test, *start;
891 char *buffer;
892
893 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000894 PyErr_SetString(PyExc_OverflowError,
895 "bytearray object is too large to make repr");
896 return NULL;
897 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200898
899 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100900 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200901 if (buffer == NULL) {
902 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000903 return NULL;
904 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000905
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200906 /* Figure out which quote to use; single is preferred */
907 quote = '\'';
908 start = PyByteArray_AS_STRING(self);
909 for (test = start; test < start+length; ++test) {
910 if (*test == '"') {
911 quote = '\''; /* back to single */
912 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000913 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200914 else if (*test == '\'')
915 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000916 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200917
918 p = buffer;
919 while (*quote_prefix)
920 *p++ = *quote_prefix++;
921 *p++ = quote;
922
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200923 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200924 for (i = 0; i < length; i++) {
925 /* There's at least enough room for a hex escape
926 and a closing quote. */
927 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200928 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200929 if (c == '\'' || c == '\\')
930 *p++ = '\\', *p++ = c;
931 else if (c == '\t')
932 *p++ = '\\', *p++ = 't';
933 else if (c == '\n')
934 *p++ = '\\', *p++ = 'n';
935 else if (c == '\r')
936 *p++ = '\\', *p++ = 'r';
937 else if (c == 0)
938 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
939 else if (c < ' ' || c >= 0x7f) {
940 *p++ = '\\';
941 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200942 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
943 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200944 }
945 else
946 *p++ = c;
947 }
948 assert(newsize - (p - buffer) >= 1);
949 *p++ = quote;
950 while (*quote_postfix) {
951 *p++ = *quote_postfix++;
952 }
953
954 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100955 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200956 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000957}
958
959static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000960bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000961{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000962 if (Py_BytesWarningFlag) {
963 if (PyErr_WarnEx(PyExc_BytesWarning,
964 "str() on a bytearray instance", 1))
965 return NULL;
966 }
967 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000968}
969
970static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000971bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000972{
973 Py_ssize_t self_size, other_size;
974 Py_buffer self_bytes, other_bytes;
975 PyObject *res;
976 Py_ssize_t minsize;
977 int cmp;
978
979 /* Bytes can be compared to anything that supports the (binary)
980 buffer API. Except that a comparison with Unicode is always an
981 error, even if the comparison is for equality. */
982 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
983 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000984 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000985 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000986 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000987 return NULL;
988 }
989
Brian Curtindfc80e32011-08-10 20:28:54 -0500990 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000991 }
992
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200993 if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000994 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -0500995 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000996 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200997 self_size = self_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000998
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200999 if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001000 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001001 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001002 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001003 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001004 other_size = other_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001005
1006 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1007 /* Shortcut: if the lengths differ, the objects differ */
1008 cmp = (op == Py_NE);
1009 }
1010 else {
1011 minsize = self_size;
1012 if (other_size < minsize)
1013 minsize = other_size;
1014
1015 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1016 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1017
1018 if (cmp == 0) {
1019 if (self_size < other_size)
1020 cmp = -1;
1021 else if (self_size > other_size)
1022 cmp = 1;
1023 }
1024
1025 switch (op) {
1026 case Py_LT: cmp = cmp < 0; break;
1027 case Py_LE: cmp = cmp <= 0; break;
1028 case Py_EQ: cmp = cmp == 0; break;
1029 case Py_NE: cmp = cmp != 0; break;
1030 case Py_GT: cmp = cmp > 0; break;
1031 case Py_GE: cmp = cmp >= 0; break;
1032 }
1033 }
1034
1035 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001036 PyBuffer_Release(&self_bytes);
1037 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001038 Py_INCREF(res);
1039 return res;
1040}
1041
1042static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001043bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001044{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001045 if (self->ob_exports > 0) {
1046 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001047 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001048 PyErr_Print();
1049 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001050 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001051 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001052 }
1053 Py_TYPE(self)->tp_free((PyObject *)self);
1054}
1055
1056
1057/* -------------------------------------------------------------------- */
1058/* Methods */
1059
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001060#define FASTSEARCH fastsearch
1061#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001062#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001063#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001064#define STRINGLIB_LEN PyByteArray_GET_SIZE
1065#define STRINGLIB_STR PyByteArray_AS_STRING
1066#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001067#define STRINGLIB_ISSPACE Py_ISSPACE
1068#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001069#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1070#define STRINGLIB_MUTABLE 1
1071
1072#include "stringlib/fastsearch.h"
1073#include "stringlib/count.h"
1074#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001075#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001076#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001077#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001078#include "stringlib/ctype.h"
1079#include "stringlib/transmogrify.h"
1080
1081
1082/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1083were copied from the old char* style string object. */
1084
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001085/* helper macro to fixup start/end slice values */
1086#define ADJUST_INDICES(start, end, len) \
1087 if (end > len) \
1088 end = len; \
1089 else if (end < 0) { \
1090 end += len; \
1091 if (end < 0) \
1092 end = 0; \
1093 } \
1094 if (start < 0) { \
1095 start += len; \
1096 if (start < 0) \
1097 start = 0; \
1098 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001099
1100Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001101bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001102{
1103 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001104 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001105 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001106 const char *sub;
1107 Py_ssize_t sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001108 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1109 Py_ssize_t res;
1110
Antoine Pitrouac65d962011-10-20 23:54:17 +02001111 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1112 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001113 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001114
1115 if (subobj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001116 if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001117 return -2;
1118
1119 sub = subbuf.buf;
1120 sub_len = subbuf.len;
1121 }
1122 else {
1123 sub = &byte;
1124 sub_len = 1;
1125 }
1126
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001127 if (dir > 0)
1128 res = stringlib_find_slice(
1129 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001130 sub, sub_len, start, end);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001131 else
1132 res = stringlib_rfind_slice(
1133 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001134 sub, sub_len, start, end);
1135
1136 if (subobj)
1137 PyBuffer_Release(&subbuf);
1138
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001139 return res;
1140}
1141
1142PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001143"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001144\n\
1145Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001146such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001147arguments start and end are interpreted as in slice notation.\n\
1148\n\
1149Return -1 on failure.");
1150
1151static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001152bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001153{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001154 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001155 if (result == -2)
1156 return NULL;
1157 return PyLong_FromSsize_t(result);
1158}
1159
1160PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001161"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001162\n\
1163Return the number of non-overlapping occurrences of subsection sub in\n\
1164bytes B[start:end]. Optional arguments start and end are interpreted\n\
1165as in slice notation.");
1166
1167static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001168bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001169{
1170 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001171 const char *str = PyByteArray_AS_STRING(self), *sub;
1172 Py_ssize_t sub_len;
1173 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001174 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001175
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001176 Py_buffer vsub;
1177 PyObject *count_obj;
1178
Antoine Pitrouac65d962011-10-20 23:54:17 +02001179 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1180 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001181 return NULL;
1182
Antoine Pitrouac65d962011-10-20 23:54:17 +02001183 if (sub_obj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001184 if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001185 return NULL;
1186
1187 sub = vsub.buf;
1188 sub_len = vsub.len;
1189 }
1190 else {
1191 sub = &byte;
1192 sub_len = 1;
1193 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001194
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001195 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001196
1197 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001198 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001199 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001200
1201 if (sub_obj)
1202 PyBuffer_Release(&vsub);
1203
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001204 return count_obj;
1205}
1206
Eli Bendersky4db28d32011-03-03 18:21:02 +00001207PyDoc_STRVAR(clear__doc__,
1208"B.clear() -> None\n\
1209\n\
1210Remove all items from B.");
1211
Victor Stinner6430fd52011-09-29 04:02:13 +02001212static PyObject *
Eli Bendersky4db28d32011-03-03 18:21:02 +00001213bytearray_clear(PyByteArrayObject *self)
1214{
1215 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1216 return NULL;
1217 Py_RETURN_NONE;
1218}
1219
1220PyDoc_STRVAR(copy__doc__,
1221"B.copy() -> bytearray\n\
1222\n\
1223Return a copy of B.");
1224
1225static PyObject *
1226bytearray_copy(PyByteArrayObject *self)
1227{
1228 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1229 PyByteArray_GET_SIZE(self));
1230}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001231
1232PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001233"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001234\n\
1235Like B.find() but raise ValueError when the subsection is not found.");
1236
1237static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001238bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001239{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001240 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001241 if (result == -2)
1242 return NULL;
1243 if (result == -1) {
1244 PyErr_SetString(PyExc_ValueError,
1245 "subsection not found");
1246 return NULL;
1247 }
1248 return PyLong_FromSsize_t(result);
1249}
1250
1251
1252PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001253"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001254\n\
1255Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001256such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001257arguments start and end are interpreted as in slice notation.\n\
1258\n\
1259Return -1 on failure.");
1260
1261static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001262bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001263{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001264 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001265 if (result == -2)
1266 return NULL;
1267 return PyLong_FromSsize_t(result);
1268}
1269
1270
1271PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001272"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001273\n\
1274Like B.rfind() but raise ValueError when the subsection is not found.");
1275
1276static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001277bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001278{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001279 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001280 if (result == -2)
1281 return NULL;
1282 if (result == -1) {
1283 PyErr_SetString(PyExc_ValueError,
1284 "subsection not found");
1285 return NULL;
1286 }
1287 return PyLong_FromSsize_t(result);
1288}
1289
1290
1291static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001292bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001293{
1294 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1295 if (ival == -1 && PyErr_Occurred()) {
1296 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001297 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001298 PyErr_Clear();
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001299 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001300 return -1;
1301 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1302 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001303 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001304 return pos >= 0;
1305 }
1306 if (ival < 0 || ival >= 256) {
1307 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1308 return -1;
1309 }
1310
Antoine Pitrou0010d372010-08-15 17:12:55 +00001311 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001312}
1313
1314
1315/* Matches the end (direction >= 0) or start (direction < 0) of self
1316 * against substr, using the start and end arguments. Returns
1317 * -1 on error, 0 if not found and 1 if found.
1318 */
1319Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001320_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001321 Py_ssize_t end, int direction)
1322{
1323 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1324 const char* str;
1325 Py_buffer vsubstr;
1326 int rv = 0;
1327
1328 str = PyByteArray_AS_STRING(self);
1329
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001330 if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001331 return -1;
1332
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001333 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001334
1335 if (direction < 0) {
1336 /* startswith */
1337 if (start+vsubstr.len > len) {
1338 goto done;
1339 }
1340 } else {
1341 /* endswith */
1342 if (end-start < vsubstr.len || start > len) {
1343 goto done;
1344 }
1345
1346 if (end-vsubstr.len > start)
1347 start = end - vsubstr.len;
1348 }
1349 if (end-start >= vsubstr.len)
1350 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1351
1352done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001353 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001354 return rv;
1355}
1356
1357
1358PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001359"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001360\n\
1361Return True if B starts with the specified prefix, False otherwise.\n\
1362With optional start, test B beginning at that position.\n\
1363With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001364prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001365
1366static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001367bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001368{
1369 Py_ssize_t start = 0;
1370 Py_ssize_t end = PY_SSIZE_T_MAX;
1371 PyObject *subobj;
1372 int result;
1373
Jesus Ceaac451502011-04-20 17:09:23 +02001374 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001375 return NULL;
1376 if (PyTuple_Check(subobj)) {
1377 Py_ssize_t i;
1378 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001379 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001380 PyTuple_GET_ITEM(subobj, i),
1381 start, end, -1);
1382 if (result == -1)
1383 return NULL;
1384 else if (result) {
1385 Py_RETURN_TRUE;
1386 }
1387 }
1388 Py_RETURN_FALSE;
1389 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001390 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001391 if (result == -1) {
1392 if (PyErr_ExceptionMatches(PyExc_TypeError))
1393 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1394 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001395 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001396 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001397 else
1398 return PyBool_FromLong(result);
1399}
1400
1401PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001402"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001403\n\
1404Return True if B ends with the specified suffix, False otherwise.\n\
1405With optional start, test B beginning at that position.\n\
1406With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001407suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001408
1409static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001410bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001411{
1412 Py_ssize_t start = 0;
1413 Py_ssize_t end = PY_SSIZE_T_MAX;
1414 PyObject *subobj;
1415 int result;
1416
Jesus Ceaac451502011-04-20 17:09:23 +02001417 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001418 return NULL;
1419 if (PyTuple_Check(subobj)) {
1420 Py_ssize_t i;
1421 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001422 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001423 PyTuple_GET_ITEM(subobj, i),
1424 start, end, +1);
1425 if (result == -1)
1426 return NULL;
1427 else if (result) {
1428 Py_RETURN_TRUE;
1429 }
1430 }
1431 Py_RETURN_FALSE;
1432 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001433 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001434 if (result == -1) {
1435 if (PyErr_ExceptionMatches(PyExc_TypeError))
1436 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1437 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001438 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001439 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001440 else
1441 return PyBool_FromLong(result);
1442}
1443
1444
1445PyDoc_STRVAR(translate__doc__,
1446"B.translate(table[, deletechars]) -> bytearray\n\
1447\n\
1448Return a copy of B, where all characters occurring in the\n\
1449optional argument deletechars are removed, and the remaining\n\
1450characters have been mapped through the given translation\n\
1451table, which must be a bytes object of length 256.");
1452
1453static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001454bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001455{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001456 char *input, *output;
1457 const char *table;
1458 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001459 PyObject *input_obj = (PyObject*)self;
1460 const char *output_start;
1461 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001462 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001463 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001464 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001465 Py_buffer vtable, vdel;
1466
1467 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1468 &tableobj, &delobj))
1469 return NULL;
1470
Georg Brandlccc47b62008-12-28 11:44:14 +00001471 if (tableobj == Py_None) {
1472 table = NULL;
1473 tableobj = NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001474 } else if (PyObject_GetBuffer(tableobj, &vtable, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001475 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001476 } else {
1477 if (vtable.len != 256) {
1478 PyErr_SetString(PyExc_ValueError,
1479 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001480 PyBuffer_Release(&vtable);
1481 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001482 }
1483 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001484 }
1485
1486 if (delobj != NULL) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001487 if (PyObject_GetBuffer(delobj, &vdel, PyBUF_SIMPLE) != 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001488 if (tableobj != NULL)
1489 PyBuffer_Release(&vtable);
1490 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001491 }
1492 }
1493 else {
1494 vdel.buf = NULL;
1495 vdel.len = 0;
1496 }
1497
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001498 inlen = PyByteArray_GET_SIZE(input_obj);
1499 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1500 if (result == NULL)
1501 goto done;
1502 output_start = output = PyByteArray_AsString(result);
1503 input = PyByteArray_AS_STRING(input_obj);
1504
Georg Brandlccc47b62008-12-28 11:44:14 +00001505 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001506 /* If no deletions are required, use faster code */
1507 for (i = inlen; --i >= 0; ) {
1508 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001509 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001510 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001511 goto done;
1512 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001513
1514 if (table == NULL) {
1515 for (i = 0; i < 256; i++)
1516 trans_table[i] = Py_CHARMASK(i);
1517 } else {
1518 for (i = 0; i < 256; i++)
1519 trans_table[i] = Py_CHARMASK(table[i]);
1520 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001521
1522 for (i = 0; i < vdel.len; i++)
1523 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1524
1525 for (i = inlen; --i >= 0; ) {
1526 c = Py_CHARMASK(*input++);
1527 if (trans_table[c] != -1)
1528 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1529 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001530 }
1531 /* Fix the size of the resulting string */
1532 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001533 if (PyByteArray_Resize(result, output - output_start) < 0) {
1534 Py_CLEAR(result);
1535 goto done;
1536 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001537
1538done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001539 if (tableobj != NULL)
1540 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001541 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001542 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001543 return result;
1544}
1545
1546
Georg Brandlabc38772009-04-12 15:51:51 +00001547static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001548bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001549{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001550 return _Py_bytes_maketrans(args);
Georg Brandlabc38772009-04-12 15:51:51 +00001551}
1552
1553
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001554/* find and count characters and substrings */
1555
1556#define findchar(target, target_len, c) \
1557 ((char *)memchr((const void *)(target), c, target_len))
1558
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001559
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001560/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001561Py_LOCAL(PyByteArrayObject *)
1562return_self(PyByteArrayObject *self)
1563{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001564 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001565 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1566 PyByteArray_AS_STRING(self),
1567 PyByteArray_GET_SIZE(self));
1568}
1569
1570Py_LOCAL_INLINE(Py_ssize_t)
1571countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1572{
1573 Py_ssize_t count=0;
1574 const char *start=target;
1575 const char *end=target+target_len;
1576
1577 while ( (start=findchar(start, end-start, c)) != NULL ) {
1578 count++;
1579 if (count >= maxcount)
1580 break;
1581 start += 1;
1582 }
1583 return count;
1584}
1585
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001586
1587/* Algorithms for different cases of string replacement */
1588
1589/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1590Py_LOCAL(PyByteArrayObject *)
1591replace_interleave(PyByteArrayObject *self,
1592 const char *to_s, Py_ssize_t to_len,
1593 Py_ssize_t maxcount)
1594{
1595 char *self_s, *result_s;
1596 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001597 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001598 PyByteArrayObject *result;
1599
1600 self_len = PyByteArray_GET_SIZE(self);
1601
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001602 /* 1 at the end plus 1 after every character;
1603 count = min(maxcount, self_len + 1) */
1604 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001605 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001606 else
1607 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1608 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001609
1610 /* Check for overflow */
1611 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001612 assert(count > 0);
1613 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001614 PyErr_SetString(PyExc_OverflowError,
1615 "replace string is too long");
1616 return NULL;
1617 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001618 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001619
1620 if (! (result = (PyByteArrayObject *)
1621 PyByteArray_FromStringAndSize(NULL, result_len)) )
1622 return NULL;
1623
1624 self_s = PyByteArray_AS_STRING(self);
1625 result_s = PyByteArray_AS_STRING(result);
1626
1627 /* TODO: special case single character, which doesn't need memcpy */
1628
1629 /* Lay the first one down (guaranteed this will occur) */
1630 Py_MEMCPY(result_s, to_s, to_len);
1631 result_s += to_len;
1632 count -= 1;
1633
1634 for (i=0; i<count; i++) {
1635 *result_s++ = *self_s++;
1636 Py_MEMCPY(result_s, to_s, to_len);
1637 result_s += to_len;
1638 }
1639
1640 /* Copy the rest of the original string */
1641 Py_MEMCPY(result_s, self_s, self_len-i);
1642
1643 return result;
1644}
1645
1646/* Special case for deleting a single character */
1647/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1648Py_LOCAL(PyByteArrayObject *)
1649replace_delete_single_character(PyByteArrayObject *self,
1650 char from_c, Py_ssize_t maxcount)
1651{
1652 char *self_s, *result_s;
1653 char *start, *next, *end;
1654 Py_ssize_t self_len, result_len;
1655 Py_ssize_t count;
1656 PyByteArrayObject *result;
1657
1658 self_len = PyByteArray_GET_SIZE(self);
1659 self_s = PyByteArray_AS_STRING(self);
1660
1661 count = countchar(self_s, self_len, from_c, maxcount);
1662 if (count == 0) {
1663 return return_self(self);
1664 }
1665
1666 result_len = self_len - count; /* from_len == 1 */
1667 assert(result_len>=0);
1668
1669 if ( (result = (PyByteArrayObject *)
1670 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1671 return NULL;
1672 result_s = PyByteArray_AS_STRING(result);
1673
1674 start = self_s;
1675 end = self_s + self_len;
1676 while (count-- > 0) {
1677 next = findchar(start, end-start, from_c);
1678 if (next == NULL)
1679 break;
1680 Py_MEMCPY(result_s, start, next-start);
1681 result_s += (next-start);
1682 start = next+1;
1683 }
1684 Py_MEMCPY(result_s, start, end-start);
1685
1686 return result;
1687}
1688
1689/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1690
1691Py_LOCAL(PyByteArrayObject *)
1692replace_delete_substring(PyByteArrayObject *self,
1693 const char *from_s, Py_ssize_t from_len,
1694 Py_ssize_t maxcount)
1695{
1696 char *self_s, *result_s;
1697 char *start, *next, *end;
1698 Py_ssize_t self_len, result_len;
1699 Py_ssize_t count, offset;
1700 PyByteArrayObject *result;
1701
1702 self_len = PyByteArray_GET_SIZE(self);
1703 self_s = PyByteArray_AS_STRING(self);
1704
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001705 count = stringlib_count(self_s, self_len,
1706 from_s, from_len,
1707 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001708
1709 if (count == 0) {
1710 /* no matches */
1711 return return_self(self);
1712 }
1713
1714 result_len = self_len - (count * from_len);
1715 assert (result_len>=0);
1716
1717 if ( (result = (PyByteArrayObject *)
1718 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1719 return NULL;
1720
1721 result_s = PyByteArray_AS_STRING(result);
1722
1723 start = self_s;
1724 end = self_s + self_len;
1725 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001726 offset = stringlib_find(start, end-start,
1727 from_s, from_len,
1728 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001729 if (offset == -1)
1730 break;
1731 next = start + offset;
1732
1733 Py_MEMCPY(result_s, start, next-start);
1734
1735 result_s += (next-start);
1736 start = next+from_len;
1737 }
1738 Py_MEMCPY(result_s, start, end-start);
1739 return result;
1740}
1741
1742/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1743Py_LOCAL(PyByteArrayObject *)
1744replace_single_character_in_place(PyByteArrayObject *self,
1745 char from_c, char to_c,
1746 Py_ssize_t maxcount)
1747{
Antoine Pitroud1188562010-06-09 16:38:55 +00001748 char *self_s, *result_s, *start, *end, *next;
1749 Py_ssize_t self_len;
1750 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001751
Antoine Pitroud1188562010-06-09 16:38:55 +00001752 /* The result string will be the same size */
1753 self_s = PyByteArray_AS_STRING(self);
1754 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001755
Antoine Pitroud1188562010-06-09 16:38:55 +00001756 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001757
Antoine Pitroud1188562010-06-09 16:38:55 +00001758 if (next == NULL) {
1759 /* No matches; return the original bytes */
1760 return return_self(self);
1761 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001762
Antoine Pitroud1188562010-06-09 16:38:55 +00001763 /* Need to make a new bytes */
1764 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1765 if (result == NULL)
1766 return NULL;
1767 result_s = PyByteArray_AS_STRING(result);
1768 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001769
Antoine Pitroud1188562010-06-09 16:38:55 +00001770 /* change everything in-place, starting with this one */
1771 start = result_s + (next-self_s);
1772 *start = to_c;
1773 start++;
1774 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001775
Antoine Pitroud1188562010-06-09 16:38:55 +00001776 while (--maxcount > 0) {
1777 next = findchar(start, end-start, from_c);
1778 if (next == NULL)
1779 break;
1780 *next = to_c;
1781 start = next+1;
1782 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001783
Antoine Pitroud1188562010-06-09 16:38:55 +00001784 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001785}
1786
1787/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1788Py_LOCAL(PyByteArrayObject *)
1789replace_substring_in_place(PyByteArrayObject *self,
1790 const char *from_s, Py_ssize_t from_len,
1791 const char *to_s, Py_ssize_t to_len,
1792 Py_ssize_t maxcount)
1793{
1794 char *result_s, *start, *end;
1795 char *self_s;
1796 Py_ssize_t self_len, offset;
1797 PyByteArrayObject *result;
1798
1799 /* The result bytes will be the same size */
1800
1801 self_s = PyByteArray_AS_STRING(self);
1802 self_len = PyByteArray_GET_SIZE(self);
1803
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001804 offset = stringlib_find(self_s, self_len,
1805 from_s, from_len,
1806 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001807 if (offset == -1) {
1808 /* No matches; return the original bytes */
1809 return return_self(self);
1810 }
1811
1812 /* Need to make a new bytes */
1813 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1814 if (result == NULL)
1815 return NULL;
1816 result_s = PyByteArray_AS_STRING(result);
1817 Py_MEMCPY(result_s, self_s, self_len);
1818
1819 /* change everything in-place, starting with this one */
1820 start = result_s + offset;
1821 Py_MEMCPY(start, to_s, from_len);
1822 start += from_len;
1823 end = result_s + self_len;
1824
1825 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001826 offset = stringlib_find(start, end-start,
1827 from_s, from_len,
1828 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001829 if (offset==-1)
1830 break;
1831 Py_MEMCPY(start+offset, to_s, from_len);
1832 start += offset+from_len;
1833 }
1834
1835 return result;
1836}
1837
1838/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1839Py_LOCAL(PyByteArrayObject *)
1840replace_single_character(PyByteArrayObject *self,
1841 char from_c,
1842 const char *to_s, Py_ssize_t to_len,
1843 Py_ssize_t maxcount)
1844{
1845 char *self_s, *result_s;
1846 char *start, *next, *end;
1847 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001848 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001849 PyByteArrayObject *result;
1850
1851 self_s = PyByteArray_AS_STRING(self);
1852 self_len = PyByteArray_GET_SIZE(self);
1853
1854 count = countchar(self_s, self_len, from_c, maxcount);
1855 if (count == 0) {
1856 /* no matches, return unchanged */
1857 return return_self(self);
1858 }
1859
1860 /* use the difference between current and new, hence the "-1" */
1861 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001862 assert(count > 0);
1863 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001864 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1865 return NULL;
1866 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001867 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001868
1869 if ( (result = (PyByteArrayObject *)
1870 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1871 return NULL;
1872 result_s = PyByteArray_AS_STRING(result);
1873
1874 start = self_s;
1875 end = self_s + self_len;
1876 while (count-- > 0) {
1877 next = findchar(start, end-start, from_c);
1878 if (next == NULL)
1879 break;
1880
1881 if (next == start) {
1882 /* replace with the 'to' */
1883 Py_MEMCPY(result_s, to_s, to_len);
1884 result_s += to_len;
1885 start += 1;
1886 } else {
1887 /* copy the unchanged old then the 'to' */
1888 Py_MEMCPY(result_s, start, next-start);
1889 result_s += (next-start);
1890 Py_MEMCPY(result_s, to_s, to_len);
1891 result_s += to_len;
1892 start = next+1;
1893 }
1894 }
1895 /* Copy the remainder of the remaining bytes */
1896 Py_MEMCPY(result_s, start, end-start);
1897
1898 return result;
1899}
1900
1901/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1902Py_LOCAL(PyByteArrayObject *)
1903replace_substring(PyByteArrayObject *self,
1904 const char *from_s, Py_ssize_t from_len,
1905 const char *to_s, Py_ssize_t to_len,
1906 Py_ssize_t maxcount)
1907{
1908 char *self_s, *result_s;
1909 char *start, *next, *end;
1910 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001911 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001912 PyByteArrayObject *result;
1913
1914 self_s = PyByteArray_AS_STRING(self);
1915 self_len = PyByteArray_GET_SIZE(self);
1916
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001917 count = stringlib_count(self_s, self_len,
1918 from_s, from_len,
1919 maxcount);
1920
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001921 if (count == 0) {
1922 /* no matches, return unchanged */
1923 return return_self(self);
1924 }
1925
1926 /* Check for overflow */
1927 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001928 assert(count > 0);
1929 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001930 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1931 return NULL;
1932 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001933 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001934
1935 if ( (result = (PyByteArrayObject *)
1936 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1937 return NULL;
1938 result_s = PyByteArray_AS_STRING(result);
1939
1940 start = self_s;
1941 end = self_s + self_len;
1942 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001943 offset = stringlib_find(start, end-start,
1944 from_s, from_len,
1945 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001946 if (offset == -1)
1947 break;
1948 next = start+offset;
1949 if (next == start) {
1950 /* replace with the 'to' */
1951 Py_MEMCPY(result_s, to_s, to_len);
1952 result_s += to_len;
1953 start += from_len;
1954 } else {
1955 /* copy the unchanged old then the 'to' */
1956 Py_MEMCPY(result_s, start, next-start);
1957 result_s += (next-start);
1958 Py_MEMCPY(result_s, to_s, to_len);
1959 result_s += to_len;
1960 start = next+from_len;
1961 }
1962 }
1963 /* Copy the remainder of the remaining bytes */
1964 Py_MEMCPY(result_s, start, end-start);
1965
1966 return result;
1967}
1968
1969
1970Py_LOCAL(PyByteArrayObject *)
1971replace(PyByteArrayObject *self,
1972 const char *from_s, Py_ssize_t from_len,
1973 const char *to_s, Py_ssize_t to_len,
1974 Py_ssize_t maxcount)
1975{
1976 if (maxcount < 0) {
1977 maxcount = PY_SSIZE_T_MAX;
1978 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1979 /* nothing to do; return the original bytes */
1980 return return_self(self);
1981 }
1982
1983 if (maxcount == 0 ||
1984 (from_len == 0 && to_len == 0)) {
1985 /* nothing to do; return the original bytes */
1986 return return_self(self);
1987 }
1988
1989 /* Handle zero-length special cases */
1990
1991 if (from_len == 0) {
1992 /* insert the 'to' bytes everywhere. */
1993 /* >>> "Python".replace("", ".") */
1994 /* '.P.y.t.h.o.n.' */
1995 return replace_interleave(self, to_s, to_len, maxcount);
1996 }
1997
1998 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1999 /* point for an empty self bytes to generate a non-empty bytes */
2000 /* Special case so the remaining code always gets a non-empty bytes */
2001 if (PyByteArray_GET_SIZE(self) == 0) {
2002 return return_self(self);
2003 }
2004
2005 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002006 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002007 if (from_len == 1) {
2008 return replace_delete_single_character(
2009 self, from_s[0], maxcount);
2010 } else {
2011 return replace_delete_substring(self, from_s, from_len, maxcount);
2012 }
2013 }
2014
2015 /* Handle special case where both bytes have the same length */
2016
2017 if (from_len == to_len) {
2018 if (from_len == 1) {
2019 return replace_single_character_in_place(
2020 self,
2021 from_s[0],
2022 to_s[0],
2023 maxcount);
2024 } else {
2025 return replace_substring_in_place(
2026 self, from_s, from_len, to_s, to_len, maxcount);
2027 }
2028 }
2029
2030 /* Otherwise use the more generic algorithms */
2031 if (from_len == 1) {
2032 return replace_single_character(self, from_s[0],
2033 to_s, to_len, maxcount);
2034 } else {
2035 /* len('from')>=2, len('to')>=1 */
2036 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2037 }
2038}
2039
2040
2041PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002042"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002043\n\
2044Return a copy of B with all occurrences of subsection\n\
2045old replaced by new. If the optional argument count is\n\
2046given, only the first count occurrences are replaced.");
2047
2048static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002049bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002050{
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002051 PyObject *res;
2052 Py_buffer old = {NULL, NULL};
2053 Py_buffer new = {NULL, NULL};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002054 Py_ssize_t count = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002055
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002056 if (!PyArg_ParseTuple(args, "y*y*|n:replace", &old, &new, &count))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002057 return NULL;
2058
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002059 res = (PyObject *)replace((PyByteArrayObject *) self,
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002060 (const char *)old.buf, old.len,
2061 (const char *)new.buf, new.len, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002062
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002063 PyBuffer_Release(&old);
2064 PyBuffer_Release(&new);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002065 return res;
2066}
2067
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002068PyDoc_STRVAR(split__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002069"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002070\n\
2071Return a list of the sections in B, using sep as the delimiter.\n\
2072If sep is not given, B is split on ASCII whitespace characters\n\
2073(space, tab, return, newline, formfeed, vertical tab).\n\
2074If maxsplit is given, at most maxsplit splits are done.");
2075
2076static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002077bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002078{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002079 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002080 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2081 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002082 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002083 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002084 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002085
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002086 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
2087 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002088 return NULL;
2089 if (maxsplit < 0)
2090 maxsplit = PY_SSIZE_T_MAX;
2091
2092 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002093 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002094
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002095 if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002096 return NULL;
2097 sub = vsub.buf;
2098 n = vsub.len;
2099
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002100 list = stringlib_split(
2101 (PyObject*) self, s, len, sub, n, maxsplit
2102 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002103 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002104 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002105}
2106
2107PyDoc_STRVAR(partition__doc__,
2108"B.partition(sep) -> (head, sep, tail)\n\
2109\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002110Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002111the separator itself, and the part after it. If the separator is not\n\
2112found, returns B and two empty bytearray objects.");
2113
2114static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002115bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002116{
2117 PyObject *bytesep, *result;
2118
2119 bytesep = PyByteArray_FromObject(sep_obj);
2120 if (! bytesep)
2121 return NULL;
2122
2123 result = stringlib_partition(
2124 (PyObject*) self,
2125 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2126 bytesep,
2127 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2128 );
2129
2130 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002131 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002132}
2133
2134PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002135"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002136\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002137Search for the separator sep in B, starting at the end of B,\n\
2138and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002139part after it. If the separator is not found, returns two empty\n\
2140bytearray objects and B.");
2141
2142static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002143bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002144{
2145 PyObject *bytesep, *result;
2146
2147 bytesep = PyByteArray_FromObject(sep_obj);
2148 if (! bytesep)
2149 return NULL;
2150
2151 result = stringlib_rpartition(
2152 (PyObject*) self,
2153 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2154 bytesep,
2155 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2156 );
2157
2158 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002159 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002160}
2161
2162PyDoc_STRVAR(rsplit__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002163"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002164\n\
2165Return a list of the sections in B, using sep as the delimiter,\n\
2166starting at the end of B and working to the front.\n\
2167If sep is not given, B is split on ASCII whitespace characters\n\
2168(space, tab, return, newline, formfeed, vertical tab).\n\
2169If maxsplit is given, at most maxsplit splits are done.");
2170
2171static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002172bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002173{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002174 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002175 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2176 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002177 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002178 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002179 Py_buffer vsub;
2180
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002181 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit",
2182 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002183 return NULL;
2184 if (maxsplit < 0)
2185 maxsplit = PY_SSIZE_T_MAX;
2186
2187 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002188 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002189
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002190 if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002191 return NULL;
2192 sub = vsub.buf;
2193 n = vsub.len;
2194
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002195 list = stringlib_rsplit(
2196 (PyObject*) self, s, len, sub, n, maxsplit
2197 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002198 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002199 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002200}
2201
2202PyDoc_STRVAR(reverse__doc__,
2203"B.reverse() -> None\n\
2204\n\
2205Reverse the order of the values in B in place.");
2206static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002207bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002208{
2209 char swap, *head, *tail;
2210 Py_ssize_t i, j, n = Py_SIZE(self);
2211
2212 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002213 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002214 tail = head + n - 1;
2215 for (i = 0; i < j; i++) {
2216 swap = *head;
2217 *head++ = *tail;
2218 *tail-- = swap;
2219 }
2220
2221 Py_RETURN_NONE;
2222}
2223
2224PyDoc_STRVAR(insert__doc__,
2225"B.insert(index, int) -> None\n\
2226\n\
2227Insert a single item into the bytearray before the given index.");
2228static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002229bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002230{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002231 PyObject *value;
2232 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002233 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002234 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002235
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002236 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002237 return NULL;
2238
2239 if (n == PY_SSIZE_T_MAX) {
2240 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002241 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002242 return NULL;
2243 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002244 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002245 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002246 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2247 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002248 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002249
2250 if (where < 0) {
2251 where += n;
2252 if (where < 0)
2253 where = 0;
2254 }
2255 if (where > n)
2256 where = n;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002257 memmove(buf + where + 1, buf + where, n - where);
2258 buf[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002259
2260 Py_RETURN_NONE;
2261}
2262
2263PyDoc_STRVAR(append__doc__,
2264"B.append(int) -> None\n\
2265\n\
2266Append a single item to the end of B.");
2267static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002268bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002269{
2270 int value;
2271 Py_ssize_t n = Py_SIZE(self);
2272
2273 if (! _getbytevalue(arg, &value))
2274 return NULL;
2275 if (n == PY_SSIZE_T_MAX) {
2276 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002277 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002278 return NULL;
2279 }
2280 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2281 return NULL;
2282
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002283 PyByteArray_AS_STRING(self)[n] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002284
2285 Py_RETURN_NONE;
2286}
2287
2288PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002289"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002290\n\
2291Append all the elements from the iterator or sequence to the\n\
2292end of B.");
2293static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002294bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002295{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002296 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002297 Py_ssize_t buf_size = 0, len = 0;
2298 int value;
2299 char *buf;
2300
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002301 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002302 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002303 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002304 return NULL;
2305
2306 Py_RETURN_NONE;
2307 }
2308
2309 it = PyObject_GetIter(arg);
2310 if (it == NULL)
2311 return NULL;
2312
Ezio Melotti42da6632011-03-15 05:18:48 +02002313 /* Try to determine the length of the argument. 32 is arbitrary. */
Armin Ronacheraa9a79d2012-10-06 14:03:24 +02002314 buf_size = PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002315 if (buf_size == -1) {
2316 Py_DECREF(it);
2317 return NULL;
2318 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002319
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002320 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002321 if (bytearray_obj == NULL) {
2322 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002323 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002324 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002325 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002326
2327 while ((item = PyIter_Next(it)) != NULL) {
2328 if (! _getbytevalue(item, &value)) {
2329 Py_DECREF(item);
2330 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002331 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002332 return NULL;
2333 }
2334 buf[len++] = value;
2335 Py_DECREF(item);
2336
2337 if (len >= buf_size) {
2338 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002339 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002340 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002341 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002342 return NULL;
2343 }
2344 /* Recompute the `buf' pointer, since the resizing operation may
2345 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002346 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002347 }
2348 }
2349 Py_DECREF(it);
2350
2351 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002352 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2353 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002354 return NULL;
2355 }
2356
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002357 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2358 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002359 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002360 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002361 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002362
2363 Py_RETURN_NONE;
2364}
2365
2366PyDoc_STRVAR(pop__doc__,
2367"B.pop([index]) -> int\n\
2368\n\
2369Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002370argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002371static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002372bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002373{
2374 int value;
2375 Py_ssize_t where = -1, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002376 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002377
2378 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2379 return NULL;
2380
2381 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002382 PyErr_SetString(PyExc_IndexError,
2383 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002384 return NULL;
2385 }
2386 if (where < 0)
2387 where += Py_SIZE(self);
2388 if (where < 0 || where >= Py_SIZE(self)) {
2389 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2390 return NULL;
2391 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002392 if (!_canresize(self))
2393 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002394
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002395 buf = PyByteArray_AS_STRING(self);
2396 value = buf[where];
2397 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002398 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2399 return NULL;
2400
Mark Dickinson54a3db92009-09-06 10:19:23 +00002401 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002402}
2403
2404PyDoc_STRVAR(remove__doc__,
2405"B.remove(int) -> None\n\
2406\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002407Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002408static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002409bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002410{
2411 int value;
2412 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002413 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002414
2415 if (! _getbytevalue(arg, &value))
2416 return NULL;
2417
2418 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002419 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002420 break;
2421 }
2422 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002423 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002424 return NULL;
2425 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002426 if (!_canresize(self))
2427 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002428
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002429 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002430 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2431 return NULL;
2432
2433 Py_RETURN_NONE;
2434}
2435
2436/* XXX These two helpers could be optimized if argsize == 1 */
2437
2438static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002439lstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002440 void *argptr, Py_ssize_t argsize)
2441{
2442 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002443 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002444 i++;
2445 return i;
2446}
2447
2448static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002449rstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002450 void *argptr, Py_ssize_t argsize)
2451{
2452 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002453 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002454 i--;
2455 return i + 1;
2456}
2457
2458PyDoc_STRVAR(strip__doc__,
2459"B.strip([bytes]) -> bytearray\n\
2460\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002461Strip leading and trailing bytes contained in the argument\n\
2462and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002463If the argument is omitted, strip ASCII whitespace.");
2464static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002465bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002466{
2467 Py_ssize_t left, right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002468 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002469 PyObject *arg = Py_None;
2470 Py_buffer varg;
2471 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2472 return NULL;
2473 if (arg == Py_None) {
2474 argptr = "\t\n\r\f\v ";
2475 argsize = 6;
2476 }
2477 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002478 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002479 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002480 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002481 argsize = varg.len;
2482 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002483 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002484 mysize = Py_SIZE(self);
2485 left = lstrip_helper(myptr, mysize, argptr, argsize);
2486 if (left == mysize)
2487 right = left;
2488 else
2489 right = rstrip_helper(myptr, mysize, argptr, argsize);
2490 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002491 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002492 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002493}
2494
2495PyDoc_STRVAR(lstrip__doc__,
2496"B.lstrip([bytes]) -> bytearray\n\
2497\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002498Strip leading bytes contained in the argument\n\
2499and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002500If the argument is omitted, strip leading ASCII whitespace.");
2501static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002502bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002503{
2504 Py_ssize_t left, right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002505 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002506 PyObject *arg = Py_None;
2507 Py_buffer varg;
2508 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2509 return NULL;
2510 if (arg == Py_None) {
2511 argptr = "\t\n\r\f\v ";
2512 argsize = 6;
2513 }
2514 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002515 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002516 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002517 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002518 argsize = varg.len;
2519 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002520 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002521 mysize = Py_SIZE(self);
2522 left = lstrip_helper(myptr, mysize, argptr, argsize);
2523 right = mysize;
2524 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002525 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002526 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002527}
2528
2529PyDoc_STRVAR(rstrip__doc__,
2530"B.rstrip([bytes]) -> bytearray\n\
2531\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002532Strip trailing bytes contained in the argument\n\
2533and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002534If the argument is omitted, strip trailing ASCII whitespace.");
2535static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002536bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002537{
Brett Cannonb94767f2011-02-22 20:15:44 +00002538 Py_ssize_t right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002539 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002540 PyObject *arg = Py_None;
2541 Py_buffer varg;
2542 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2543 return NULL;
2544 if (arg == Py_None) {
2545 argptr = "\t\n\r\f\v ";
2546 argsize = 6;
2547 }
2548 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002549 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002550 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002551 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002552 argsize = varg.len;
2553 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002554 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002555 mysize = Py_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002556 right = rstrip_helper(myptr, mysize, argptr, argsize);
2557 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002558 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002559 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002560}
2561
2562PyDoc_STRVAR(decode_doc,
Victor Stinnerc911bbf2010-11-07 19:04:46 +00002563"B.decode(encoding='utf-8', errors='strict') -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002564\n\
Victor Stinnere14e2122010-11-07 18:41:46 +00002565Decode B using the codec registered for encoding. Default encoding\n\
2566is 'utf-8'. errors may be given to set a different error\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002567handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2568a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2569as well as any other name registered with codecs.register_error that is\n\
2570able to handle UnicodeDecodeErrors.");
2571
2572static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002573bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002574{
2575 const char *encoding = NULL;
2576 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002577 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002578
Benjamin Peterson308d6372009-09-18 21:42:35 +00002579 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002580 return NULL;
2581 if (encoding == NULL)
2582 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002583 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002584}
2585
2586PyDoc_STRVAR(alloc_doc,
2587"B.__alloc__() -> int\n\
2588\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002589Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002590
2591static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002592bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002593{
2594 return PyLong_FromSsize_t(self->ob_alloc);
2595}
2596
2597PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002598"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002599\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002600Concatenate any number of bytes/bytearray objects, with B\n\
2601in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002602
2603static PyObject *
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002604bytearray_join(PyObject *self, PyObject *iterable)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002605{
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002606 return stringlib_bytes_join(self, iterable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002607}
2608
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002609PyDoc_STRVAR(splitlines__doc__,
2610"B.splitlines([keepends]) -> list of lines\n\
2611\n\
2612Return a list of the lines in B, breaking at line boundaries.\n\
2613Line breaks are not included in the resulting list unless keepends\n\
2614is given and true.");
2615
2616static PyObject*
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002617bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002618{
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002619 static char *kwlist[] = {"keepends", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002620 int keepends = 0;
2621
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002622 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines",
2623 kwlist, &keepends))
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002624 return NULL;
2625
2626 return stringlib_splitlines(
2627 (PyObject*) self, PyByteArray_AS_STRING(self),
2628 PyByteArray_GET_SIZE(self), keepends
2629 );
2630}
2631
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002632PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002633"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002634\n\
2635Create a bytearray object from a string of hexadecimal numbers.\n\
2636Spaces between two numbers are accepted.\n\
2637Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2638
2639static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002640hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002641{
2642 if (c >= 128)
2643 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002644 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002645 return c - '0';
2646 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002647 if (Py_ISUPPER(c))
2648 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002649 if (c >= 'a' && c <= 'f')
2650 return c - 'a' + 10;
2651 }
2652 return -1;
2653}
2654
2655static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002656bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002657{
2658 PyObject *newbytes, *hexobj;
2659 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002660 Py_ssize_t hexlen, byteslen, i, j;
2661 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002662 void *data;
2663 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002664
2665 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2666 return NULL;
2667 assert(PyUnicode_Check(hexobj));
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002668 if (PyUnicode_READY(hexobj))
2669 return NULL;
2670 kind = PyUnicode_KIND(hexobj);
2671 data = PyUnicode_DATA(hexobj);
2672 hexlen = PyUnicode_GET_LENGTH(hexobj);
2673
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002674 byteslen = hexlen/2; /* This overestimates if there are spaces */
2675 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2676 if (!newbytes)
2677 return NULL;
2678 buf = PyByteArray_AS_STRING(newbytes);
2679 for (i = j = 0; i < hexlen; i += 2) {
2680 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002681 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002682 i++;
2683 if (i >= hexlen)
2684 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002685 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2686 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002687 if (top == -1 || bot == -1) {
2688 PyErr_Format(PyExc_ValueError,
2689 "non-hexadecimal number found in "
2690 "fromhex() arg at position %zd", i);
2691 goto error;
2692 }
2693 buf[j++] = (top << 4) + bot;
2694 }
2695 if (PyByteArray_Resize(newbytes, j) < 0)
2696 goto error;
2697 return newbytes;
2698
2699 error:
2700 Py_DECREF(newbytes);
2701 return NULL;
2702}
2703
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002704
2705static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002706_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002707{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002708 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002709 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002710 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002711
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002712 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002713 if (dict == NULL) {
2714 PyErr_Clear();
2715 dict = Py_None;
2716 Py_INCREF(dict);
2717 }
2718
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002719 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002720 if (proto < 3) {
2721 /* use str based reduction for backwards compatibility with Python 2.x */
2722 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002723 if (Py_SIZE(self))
2724 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002725 else
2726 latin1 = PyUnicode_FromString("");
2727 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2728 }
2729 else {
2730 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002731 if (Py_SIZE(self)) {
2732 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002733 }
2734 else {
2735 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2736 }
2737 }
2738}
2739
2740PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2741
2742static PyObject *
2743bytearray_reduce(PyByteArrayObject *self)
2744{
2745 return _common_reduce(self, 2);
2746}
2747
2748PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling.");
2749
2750static PyObject *
2751bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
2752{
2753 int proto = 0;
2754
2755 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
2756 return NULL;
2757
2758 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002759}
2760
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002761PyDoc_STRVAR(sizeof_doc,
2762"B.__sizeof__() -> int\n\
2763 \n\
2764Returns the size of B in memory, in bytes");
2765static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002766bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002767{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002768 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002769
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002770 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2771 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002772}
2773
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002774static PySequenceMethods bytearray_as_sequence = {
2775 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002776 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002777 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2778 (ssizeargfunc)bytearray_getitem, /* sq_item */
2779 0, /* sq_slice */
2780 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2781 0, /* sq_ass_slice */
2782 (objobjproc)bytearray_contains, /* sq_contains */
2783 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2784 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002785};
2786
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002787static PyMappingMethods bytearray_as_mapping = {
2788 (lenfunc)bytearray_length,
2789 (binaryfunc)bytearray_subscript,
2790 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002791};
2792
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002793static PyBufferProcs bytearray_as_buffer = {
2794 (getbufferproc)bytearray_getbuffer,
2795 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002796};
2797
2798static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002799bytearray_methods[] = {
2800 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2801 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002802 {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002803 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2804 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002805 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2806 _Py_capitalize__doc__},
2807 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00002808 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__},
2809 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002810 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002811 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002812 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Ezio Melotti745d54d2013-11-16 19:10:57 +02002813 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002814 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002815 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2816 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2817 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002818 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002819 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2820 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002821 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2822 _Py_isalnum__doc__},
2823 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2824 _Py_isalpha__doc__},
2825 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2826 _Py_isdigit__doc__},
2827 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2828 _Py_islower__doc__},
2829 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2830 _Py_isspace__doc__},
2831 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2832 _Py_istitle__doc__},
2833 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2834 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002835 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002836 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2837 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002838 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2839 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002840 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002841 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2842 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2843 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2844 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2845 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2846 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2847 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002848 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002849 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002850 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002851 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002852 {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__},
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002853 {"splitlines", (PyCFunction)bytearray_splitlines,
2854 METH_VARARGS | METH_KEYWORDS, splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002855 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002856 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002857 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002858 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2859 _Py_swapcase__doc__},
2860 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002861 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002862 translate__doc__},
2863 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2864 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2865 {NULL}
2866};
2867
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002868PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002869"bytearray(iterable_of_ints) -> bytearray\n\
2870bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002871bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2872bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2873bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002874\n\
2875Construct an mutable bytearray object from:\n\
2876 - an iterable yielding integers in range(256)\n\
2877 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002878 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002879 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002880 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002881
2882
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002883static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002884
2885PyTypeObject PyByteArray_Type = {
2886 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2887 "bytearray",
2888 sizeof(PyByteArrayObject),
2889 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002890 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002891 0, /* tp_print */
2892 0, /* tp_getattr */
2893 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002894 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002895 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002896 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002897 &bytearray_as_sequence, /* tp_as_sequence */
2898 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002899 0, /* tp_hash */
2900 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002901 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002902 PyObject_GenericGetAttr, /* tp_getattro */
2903 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002904 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002905 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002906 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002907 0, /* tp_traverse */
2908 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002909 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002910 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002911 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002912 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002913 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002914 0, /* tp_members */
2915 0, /* tp_getset */
2916 0, /* tp_base */
2917 0, /* tp_dict */
2918 0, /* tp_descr_get */
2919 0, /* tp_descr_set */
2920 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002921 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002922 PyType_GenericAlloc, /* tp_alloc */
2923 PyType_GenericNew, /* tp_new */
2924 PyObject_Del, /* tp_free */
2925};
2926
2927/*********************** Bytes Iterator ****************************/
2928
2929typedef struct {
2930 PyObject_HEAD
2931 Py_ssize_t it_index;
2932 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2933} bytesiterobject;
2934
2935static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002936bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002937{
2938 _PyObject_GC_UNTRACK(it);
2939 Py_XDECREF(it->it_seq);
2940 PyObject_GC_Del(it);
2941}
2942
2943static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002944bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002945{
2946 Py_VISIT(it->it_seq);
2947 return 0;
2948}
2949
2950static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002951bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002952{
2953 PyByteArrayObject *seq;
2954 PyObject *item;
2955
2956 assert(it != NULL);
2957 seq = it->it_seq;
2958 if (seq == NULL)
2959 return NULL;
2960 assert(PyByteArray_Check(seq));
2961
2962 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2963 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002964 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002965 if (item != NULL)
2966 ++it->it_index;
2967 return item;
2968 }
2969
2970 Py_DECREF(seq);
2971 it->it_seq = NULL;
2972 return NULL;
2973}
2974
2975static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002976bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002977{
2978 Py_ssize_t len = 0;
2979 if (it->it_seq)
2980 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2981 return PyLong_FromSsize_t(len);
2982}
2983
2984PyDoc_STRVAR(length_hint_doc,
2985 "Private method returning an estimate of len(list(it)).");
2986
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002987static PyObject *
2988bytearrayiter_reduce(bytesiterobject *it)
2989{
2990 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02002991 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002992 it->it_seq, it->it_index);
2993 } else {
2994 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
2995 if (u == NULL)
2996 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02002997 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002998 }
2999}
3000
3001static PyObject *
3002bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3003{
3004 Py_ssize_t index = PyLong_AsSsize_t(state);
3005 if (index == -1 && PyErr_Occurred())
3006 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +00003007 if (it->it_seq != NULL) {
3008 if (index < 0)
3009 index = 0;
3010 else if (index > PyByteArray_GET_SIZE(it->it_seq))
3011 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
3012 it->it_index = index;
3013 }
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003014 Py_RETURN_NONE;
3015}
3016
3017PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3018
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003019static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003020 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003021 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003022 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
3023 reduce_doc},
3024 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3025 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003026 {NULL, NULL} /* sentinel */
3027};
3028
3029PyTypeObject PyByteArrayIter_Type = {
3030 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3031 "bytearray_iterator", /* tp_name */
3032 sizeof(bytesiterobject), /* tp_basicsize */
3033 0, /* tp_itemsize */
3034 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003035 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003036 0, /* tp_print */
3037 0, /* tp_getattr */
3038 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003039 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003040 0, /* tp_repr */
3041 0, /* tp_as_number */
3042 0, /* tp_as_sequence */
3043 0, /* tp_as_mapping */
3044 0, /* tp_hash */
3045 0, /* tp_call */
3046 0, /* tp_str */
3047 PyObject_GenericGetAttr, /* tp_getattro */
3048 0, /* tp_setattro */
3049 0, /* tp_as_buffer */
3050 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3051 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003052 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003053 0, /* tp_clear */
3054 0, /* tp_richcompare */
3055 0, /* tp_weaklistoffset */
3056 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003057 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3058 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003059 0,
3060};
3061
3062static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003063bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003064{
3065 bytesiterobject *it;
3066
3067 if (!PyByteArray_Check(seq)) {
3068 PyErr_BadInternalCall();
3069 return NULL;
3070 }
3071 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3072 if (it == NULL)
3073 return NULL;
3074 it->it_index = 0;
3075 Py_INCREF(seq);
3076 it->it_seq = (PyByteArrayObject *)seq;
3077 _PyObject_GC_TRACK(it);
3078 return (PyObject *)it;
3079}