blob: 68b9c4a22fa81c4d4be7de22ee72a75420b8bc69 [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
77static Py_ssize_t
78_getbuffer(PyObject *obj, Py_buffer *view)
79{
80 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
81
82 if (buffer == NULL || buffer->bf_getbuffer == NULL)
83 {
84 PyErr_Format(PyExc_TypeError,
85 "Type %.100s doesn't support the buffer API",
86 Py_TYPE(obj)->tp_name);
87 return -1;
88 }
89
90 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
91 return -1;
92 return view->len;
93}
94
Antoine Pitrou5504e892008-12-06 21:27:53 +000095static int
96_canresize(PyByteArrayObject *self)
97{
98 if (self->ob_exports > 0) {
99 PyErr_SetString(PyExc_BufferError,
100 "Existing exports of data: object cannot be re-sized");
101 return 0;
102 }
103 return 1;
104}
105
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000106/* Direct API functions */
107
108PyObject *
109PyByteArray_FromObject(PyObject *input)
110{
111 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
112 input, NULL);
113}
114
115PyObject *
116PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
117{
118 PyByteArrayObject *new;
119 Py_ssize_t alloc;
120
121 if (size < 0) {
122 PyErr_SetString(PyExc_SystemError,
123 "Negative size passed to PyByteArray_FromStringAndSize");
124 return NULL;
125 }
126
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000127 /* Prevent buffer overflow when setting alloc to size+1. */
128 if (size == PY_SSIZE_T_MAX) {
129 return PyErr_NoMemory();
130 }
131
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000132 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
133 if (new == NULL)
134 return NULL;
135
136 if (size == 0) {
137 new->ob_bytes = NULL;
138 alloc = 0;
139 }
140 else {
141 alloc = size + 1;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100142 new->ob_bytes = PyObject_Malloc(alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000143 if (new->ob_bytes == NULL) {
144 Py_DECREF(new);
145 return PyErr_NoMemory();
146 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +0000147 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000148 memcpy(new->ob_bytes, bytes, size);
149 new->ob_bytes[size] = '\0'; /* Trailing null byte */
150 }
151 Py_SIZE(new) = size;
152 new->ob_alloc = alloc;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200153 new->ob_start = new->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000154 new->ob_exports = 0;
155
156 return (PyObject *)new;
157}
158
159Py_ssize_t
160PyByteArray_Size(PyObject *self)
161{
162 assert(self != NULL);
163 assert(PyByteArray_Check(self));
164
165 return PyByteArray_GET_SIZE(self);
166}
167
168char *
169PyByteArray_AsString(PyObject *self)
170{
171 assert(self != NULL);
172 assert(PyByteArray_Check(self));
173
174 return PyByteArray_AS_STRING(self);
175}
176
177int
178PyByteArray_Resize(PyObject *self, Py_ssize_t size)
179{
180 void *sval;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200181 PyByteArrayObject *obj = ((PyByteArrayObject *)self);
182 Py_ssize_t alloc = obj->ob_alloc;
183 Py_ssize_t logical_offset = obj->ob_start - obj->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000184
185 assert(self != NULL);
186 assert(PyByteArray_Check(self));
187 assert(size >= 0);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200188 assert(logical_offset >= 0);
189 assert(logical_offset <= alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000190
Antoine Pitrou5504e892008-12-06 21:27:53 +0000191 if (size == Py_SIZE(self)) {
192 return 0;
193 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200194 if (!_canresize(obj)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000195 return -1;
196 }
197
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200198 if (size + logical_offset + 1 < alloc) {
199 /* Current buffer is large enough to host the requested size,
200 decide on a strategy. */
201 if (size < alloc / 2) {
202 /* Major downsize; resize down to exact size */
203 alloc = size + 1;
204 }
205 else {
206 /* Minor downsize; quick exit */
207 Py_SIZE(self) = size;
208 PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
209 return 0;
210 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000211 }
212 else {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200213 /* Need growing, decide on a strategy */
214 if (size <= alloc * 1.125) {
215 /* Moderate upsize; overallocate similar to list_resize() */
216 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
217 }
218 else {
219 /* Major upsize; resize up to exact size */
220 alloc = size + 1;
221 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000222 }
223
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200224 if (logical_offset > 0) {
225 sval = PyObject_Malloc(alloc);
226 if (sval == NULL) {
227 PyErr_NoMemory();
228 return -1;
229 }
230 memcpy(sval, PyByteArray_AS_STRING(self), Py_MIN(size, Py_SIZE(self)));
231 PyObject_Free(obj->ob_bytes);
232 }
233 else {
234 sval = PyObject_Realloc(obj->ob_bytes, alloc);
235 if (sval == NULL) {
236 PyErr_NoMemory();
237 return -1;
238 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000239 }
240
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200241 obj->ob_bytes = obj->ob_start = sval;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000242 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200243 obj->ob_alloc = alloc;
244 obj->ob_bytes[size] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000245
246 return 0;
247}
248
249PyObject *
250PyByteArray_Concat(PyObject *a, PyObject *b)
251{
252 Py_ssize_t size;
253 Py_buffer va, vb;
254 PyByteArrayObject *result = NULL;
255
256 va.len = -1;
257 vb.len = -1;
258 if (_getbuffer(a, &va) < 0 ||
259 _getbuffer(b, &vb) < 0) {
260 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
261 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
262 goto done;
263 }
264
265 size = va.len + vb.len;
266 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000267 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000268 goto done;
269 }
270
271 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
272 if (result != NULL) {
273 memcpy(result->ob_bytes, va.buf, va.len);
274 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
275 }
276
277 done:
278 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000279 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000280 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000281 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000282 return (PyObject *)result;
283}
284
285/* Functions stuffed into the type object */
286
287static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000288bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000289{
290 return Py_SIZE(self);
291}
292
293static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000294bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000295{
296 Py_ssize_t mysize;
297 Py_ssize_t size;
298 Py_buffer vo;
299
300 if (_getbuffer(other, &vo) < 0) {
301 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
302 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
303 return NULL;
304 }
305
306 mysize = Py_SIZE(self);
307 size = mysize + vo.len;
308 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000309 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000310 return PyErr_NoMemory();
311 }
312 if (size < self->ob_alloc) {
313 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200314 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000315 }
316 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000317 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000318 return NULL;
319 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200320 memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000321 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000322 Py_INCREF(self);
323 return (PyObject *)self;
324}
325
326static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000327bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000328{
329 PyByteArrayObject *result;
330 Py_ssize_t mysize;
331 Py_ssize_t size;
332
333 if (count < 0)
334 count = 0;
335 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000336 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000337 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000338 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000339 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
340 if (result != NULL && size != 0) {
341 if (mysize == 1)
342 memset(result->ob_bytes, self->ob_bytes[0], size);
343 else {
344 Py_ssize_t i;
345 for (i = 0; i < count; i++)
346 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
347 }
348 }
349 return (PyObject *)result;
350}
351
352static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000353bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000354{
355 Py_ssize_t mysize;
356 Py_ssize_t size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200357 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000358
359 if (count < 0)
360 count = 0;
361 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000362 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000363 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000364 size = mysize * count;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200365 if (PyByteArray_Resize((PyObject *)self, size) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000366 return NULL;
367
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200368 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000369 if (mysize == 1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200370 memset(buf, buf[0], size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000371 else {
372 Py_ssize_t i;
373 for (i = 1; i < count; i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200374 memcpy(buf + i*mysize, buf, mysize);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000375 }
376
377 Py_INCREF(self);
378 return (PyObject *)self;
379}
380
381static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000382bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000383{
384 if (i < 0)
385 i += Py_SIZE(self);
386 if (i < 0 || i >= Py_SIZE(self)) {
387 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
388 return NULL;
389 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200390 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000391}
392
393static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000394bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000395{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000396 if (PyIndex_Check(index)) {
397 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000398
399 if (i == -1 && PyErr_Occurred())
400 return NULL;
401
402 if (i < 0)
403 i += PyByteArray_GET_SIZE(self);
404
405 if (i < 0 || i >= Py_SIZE(self)) {
406 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
407 return NULL;
408 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200409 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000410 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000411 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000412 Py_ssize_t start, stop, step, slicelength, cur, i;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000413 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000414 PyByteArray_GET_SIZE(self),
415 &start, &stop, &step, &slicelength) < 0) {
416 return NULL;
417 }
418
419 if (slicelength <= 0)
420 return PyByteArray_FromStringAndSize("", 0);
421 else if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200422 return PyByteArray_FromStringAndSize(
423 PyByteArray_AS_STRING(self) + start, slicelength);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000424 }
425 else {
426 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000427 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000428 PyObject *result;
429
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000430 result = PyByteArray_FromStringAndSize(NULL, slicelength);
431 if (result == NULL)
432 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000433
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000434 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000435 for (cur = start, i = 0; i < slicelength;
436 cur += step, i++) {
437 result_buf[i] = source_buf[cur];
438 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000439 return result;
440 }
441 }
442 else {
443 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
444 return NULL;
445 }
446}
447
448static int
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200449bytearray_setslice_linear(PyByteArrayObject *self,
450 Py_ssize_t lo, Py_ssize_t hi,
451 char *bytes, Py_ssize_t bytes_len)
452{
453 Py_ssize_t avail = hi - lo;
454 char *buf = PyByteArray_AS_STRING(self);
455 Py_ssize_t growth = bytes_len - avail;
Victor Stinner84557232013-11-21 12:29:51 +0100456 int res = 0;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200457 assert(avail >= 0);
458
Victor Stinner84557232013-11-21 12:29:51 +0100459 if (growth < 0) {
460 if (!_canresize(self))
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200461 return -1;
Victor Stinner84557232013-11-21 12:29:51 +0100462
463 if (lo == 0) {
464 /* Shrink the buffer by advancing its logical start */
465 self->ob_start -= growth;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200466 /*
Victor Stinner84557232013-11-21 12:29:51 +0100467 0 lo hi old_size
468 | |<----avail----->|<-----tail------>|
469 | |<-bytes_len->|<-----tail------>|
470 0 new_lo new_hi new_size
471 */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200472 }
Victor Stinner84557232013-11-21 12:29:51 +0100473 else {
474 /*
475 0 lo hi old_size
476 | |<----avail----->|<-----tomove------>|
477 | |<-bytes_len->|<-----tomove------>|
478 0 lo new_hi new_size
479 */
480 memmove(buf + lo + bytes_len, buf + hi,
481 Py_SIZE(self) - hi);
482 }
483 if (PyByteArray_Resize((PyObject *)self,
484 Py_SIZE(self) + growth) < 0) {
485 /* Issue #19578: Handling the memory allocation failure here is
486 tricky here because the bytearray object has already been
487 modified. Depending on growth and lo, the behaviour is
488 different.
489
490 If growth < 0 and lo != 0, the operation is completed, but a
491 MemoryError is still raised and the memory block is not
492 shrinked. Otherwise, the bytearray is restored in its previous
493 state and a MemoryError is raised. */
494 if (lo == 0) {
495 self->ob_start += growth;
496 return -1;
497 }
498 /* memmove() removed bytes, the bytearray object cannot be
499 restored in its previous state. */
500 Py_SIZE(self) += growth;
501 res = -1;
502 }
503 buf = PyByteArray_AS_STRING(self);
504 }
505 else if (growth > 0) {
506 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
507 PyErr_NoMemory();
508 return -1;
509 }
510
511 if (PyByteArray_Resize((PyObject *)self,
512 Py_SIZE(self) + growth) < 0) {
513 return -1;
514 }
515 buf = PyByteArray_AS_STRING(self);
516 /* Make the place for the additional bytes */
517 /*
518 0 lo hi old_size
519 | |<-avail->|<-----tomove------>|
520 | |<---bytes_len-->|<-----tomove------>|
521 0 lo new_hi new_size
522 */
523 memmove(buf + lo + bytes_len, buf + hi,
524 Py_SIZE(self) - lo - bytes_len);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200525 }
526
527 if (bytes_len > 0)
528 memcpy(buf + lo, bytes, bytes_len);
Victor Stinner84557232013-11-21 12:29:51 +0100529 return res;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200530}
531
532static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000533bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000534 PyObject *values)
535{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200536 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000537 void *bytes;
538 Py_buffer vbytes;
539 int res = 0;
540
541 vbytes.len = -1;
542 if (values == (PyObject *)self) {
543 /* Make a copy and call this function recursively */
544 int err;
545 values = PyByteArray_FromObject(values);
546 if (values == NULL)
547 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000548 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000549 Py_DECREF(values);
550 return err;
551 }
552 if (values == NULL) {
553 /* del b[lo:hi] */
554 bytes = NULL;
555 needed = 0;
556 }
557 else {
558 if (_getbuffer(values, &vbytes) < 0) {
559 PyErr_Format(PyExc_TypeError,
Georg Brandl3dbca812008-07-23 16:10:53 +0000560 "can't set bytearray slice from %.100s",
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000561 Py_TYPE(values)->tp_name);
562 return -1;
563 }
564 needed = vbytes.len;
565 bytes = vbytes.buf;
566 }
567
568 if (lo < 0)
569 lo = 0;
570 if (hi < lo)
571 hi = lo;
572 if (hi > Py_SIZE(self))
573 hi = Py_SIZE(self);
574
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200575 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000576 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200577 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000578 return res;
579}
580
581static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000582bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000583{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000584 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000585
586 if (i < 0)
587 i += Py_SIZE(self);
588
589 if (i < 0 || i >= Py_SIZE(self)) {
590 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
591 return -1;
592 }
593
594 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000595 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000596
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000597 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000598 return -1;
599
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200600 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000601 return 0;
602}
603
604static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000605bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000606{
607 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200608 char *buf, *bytes;
609 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000610
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000611 if (PyIndex_Check(index)) {
612 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000613
614 if (i == -1 && PyErr_Occurred())
615 return -1;
616
617 if (i < 0)
618 i += PyByteArray_GET_SIZE(self);
619
620 if (i < 0 || i >= Py_SIZE(self)) {
621 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
622 return -1;
623 }
624
625 if (values == NULL) {
626 /* Fall through to slice assignment */
627 start = i;
628 stop = i + 1;
629 step = 1;
630 slicelen = 1;
631 }
632 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000633 int ival;
634 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000635 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200636 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000637 return 0;
638 }
639 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000640 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000641 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000642 PyByteArray_GET_SIZE(self),
643 &start, &stop, &step, &slicelen) < 0) {
644 return -1;
645 }
646 }
647 else {
648 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
649 return -1;
650 }
651
652 if (values == NULL) {
653 bytes = NULL;
654 needed = 0;
655 }
656 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100657 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200658 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
659 PyErr_SetString(PyExc_TypeError,
660 "can assign only bytes, buffers, or iterables "
661 "of ints in range(0, 256)");
662 return -1;
663 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000664 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000665 values = PyByteArray_FromObject(values);
666 if (values == NULL)
667 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000668 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000669 Py_DECREF(values);
670 return err;
671 }
672 else {
673 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200674 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000675 needed = Py_SIZE(values);
676 }
677 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
678 if ((step < 0 && start < stop) ||
679 (step > 0 && start > stop))
680 stop = start;
681 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200682 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000683 }
684 else {
685 if (needed == 0) {
686 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000687 size_t cur;
688 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000689
Antoine Pitrou5504e892008-12-06 21:27:53 +0000690 if (!_canresize(self))
691 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000692
693 if (slicelen == 0)
694 /* Nothing to do here. */
695 return 0;
696
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000697 if (step < 0) {
698 stop = start + 1;
699 start = stop + step * (slicelen - 1) - 1;
700 step = -step;
701 }
702 for (cur = start, i = 0;
703 i < slicelen; cur += step, i++) {
704 Py_ssize_t lim = step - 1;
705
Mark Dickinson66f575b2010-02-14 12:53:32 +0000706 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000707 lim = PyByteArray_GET_SIZE(self) - cur - 1;
708
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200709 memmove(buf + cur - i,
710 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000711 }
712 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000713 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000714 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200715 memmove(buf + cur - slicelen,
716 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000717 PyByteArray_GET_SIZE(self) - cur);
718 }
719 if (PyByteArray_Resize((PyObject *)self,
720 PyByteArray_GET_SIZE(self) - slicelen) < 0)
721 return -1;
722
723 return 0;
724 }
725 else {
726 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000727 Py_ssize_t i;
728 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000729
730 if (needed != slicelen) {
731 PyErr_Format(PyExc_ValueError,
732 "attempt to assign bytes of size %zd "
733 "to extended slice of size %zd",
734 needed, slicelen);
735 return -1;
736 }
737 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200738 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000739 return 0;
740 }
741 }
742}
743
744static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000745bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000746{
747 static char *kwlist[] = {"source", "encoding", "errors", 0};
748 PyObject *arg = NULL;
749 const char *encoding = NULL;
750 const char *errors = NULL;
751 Py_ssize_t count;
752 PyObject *it;
753 PyObject *(*iternext)(PyObject *);
754
755 if (Py_SIZE(self) != 0) {
756 /* Empty previous contents (yes, do this first of all!) */
757 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
758 return -1;
759 }
760
761 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000762 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000763 &arg, &encoding, &errors))
764 return -1;
765
766 /* Make a quick exit if no first argument */
767 if (arg == NULL) {
768 if (encoding != NULL || errors != NULL) {
769 PyErr_SetString(PyExc_TypeError,
770 "encoding or errors without sequence argument");
771 return -1;
772 }
773 return 0;
774 }
775
776 if (PyUnicode_Check(arg)) {
777 /* Encode via the codec registry */
778 PyObject *encoded, *new;
779 if (encoding == NULL) {
780 PyErr_SetString(PyExc_TypeError,
781 "string argument without an encoding");
782 return -1;
783 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000784 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000785 if (encoded == NULL)
786 return -1;
787 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000788 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000789 Py_DECREF(encoded);
790 if (new == NULL)
791 return -1;
792 Py_DECREF(new);
793 return 0;
794 }
795
796 /* If it's not unicode, there can't be encoding or errors */
797 if (encoding != NULL || errors != NULL) {
798 PyErr_SetString(PyExc_TypeError,
799 "encoding or errors without a string argument");
800 return -1;
801 }
802
803 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000804 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
805 if (count == -1 && PyErr_Occurred()) {
806 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000807 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000808 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000809 }
810 else if (count < 0) {
811 PyErr_SetString(PyExc_ValueError, "negative count");
812 return -1;
813 }
814 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000815 if (count > 0) {
Victor Stinnerdb067af2014-05-02 22:31:14 +0200816 void *sval;
817 Py_ssize_t alloc;
818
819 assert (Py_SIZE(self) == 0);
820
821 alloc = count + 1;
822 sval = PyObject_Calloc(1, alloc);
823 if (sval == NULL)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000824 return -1;
Victor Stinnerdb067af2014-05-02 22:31:14 +0200825
826 PyObject_Free(self->ob_bytes);
827
828 self->ob_bytes = self->ob_start = sval;
829 Py_SIZE(self) = count;
830 self->ob_alloc = alloc;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000831 }
832 return 0;
833 }
834
835 /* Use the buffer API */
836 if (PyObject_CheckBuffer(arg)) {
837 Py_ssize_t size;
838 Py_buffer view;
839 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
840 return -1;
841 size = view.len;
842 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200843 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
844 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200845 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000846 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000847 return 0;
848 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000849 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000850 return -1;
851 }
852
853 /* XXX Optimize this if the arguments is a list, tuple */
854
855 /* Get the iterator */
856 it = PyObject_GetIter(arg);
857 if (it == NULL)
858 return -1;
859 iternext = *Py_TYPE(it)->tp_iternext;
860
861 /* Run the iterator to exhaustion */
862 for (;;) {
863 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000864 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000865
866 /* Get the next item */
867 item = iternext(it);
868 if (item == NULL) {
869 if (PyErr_Occurred()) {
870 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
871 goto error;
872 PyErr_Clear();
873 }
874 break;
875 }
876
877 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000878 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000879 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000880 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000881 goto error;
882
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000883 /* Append the byte */
884 if (Py_SIZE(self) < self->ob_alloc)
885 Py_SIZE(self)++;
886 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
887 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200888 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000889 }
890
891 /* Clean up and return success */
892 Py_DECREF(it);
893 return 0;
894
895 error:
896 /* Error handling when it != NULL */
897 Py_DECREF(it);
898 return -1;
899}
900
901/* Mostly copied from string_repr, but without the
902 "smart quote" functionality. */
903static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000904bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000905{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000906 const char *quote_prefix = "bytearray(b";
907 const char *quote_postfix = ")";
908 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200909 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000910 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000911 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200912 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200913 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200914 char c;
915 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200916 int quote;
917 char *test, *start;
918 char *buffer;
919
920 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000921 PyErr_SetString(PyExc_OverflowError,
922 "bytearray object is too large to make repr");
923 return NULL;
924 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200925
926 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100927 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200928 if (buffer == NULL) {
929 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000930 return NULL;
931 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000932
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200933 /* Figure out which quote to use; single is preferred */
934 quote = '\'';
935 start = PyByteArray_AS_STRING(self);
936 for (test = start; test < start+length; ++test) {
937 if (*test == '"') {
938 quote = '\''; /* back to single */
939 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000940 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200941 else if (*test == '\'')
942 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000943 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200944
945 p = buffer;
946 while (*quote_prefix)
947 *p++ = *quote_prefix++;
948 *p++ = quote;
949
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200950 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200951 for (i = 0; i < length; i++) {
952 /* There's at least enough room for a hex escape
953 and a closing quote. */
954 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200955 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200956 if (c == '\'' || c == '\\')
957 *p++ = '\\', *p++ = c;
958 else if (c == '\t')
959 *p++ = '\\', *p++ = 't';
960 else if (c == '\n')
961 *p++ = '\\', *p++ = 'n';
962 else if (c == '\r')
963 *p++ = '\\', *p++ = 'r';
964 else if (c == 0)
965 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
966 else if (c < ' ' || c >= 0x7f) {
967 *p++ = '\\';
968 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200969 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
970 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200971 }
972 else
973 *p++ = c;
974 }
975 assert(newsize - (p - buffer) >= 1);
976 *p++ = quote;
977 while (*quote_postfix) {
978 *p++ = *quote_postfix++;
979 }
980
981 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100982 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200983 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000984}
985
986static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000987bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000988{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000989 if (Py_BytesWarningFlag) {
990 if (PyErr_WarnEx(PyExc_BytesWarning,
991 "str() on a bytearray instance", 1))
992 return NULL;
993 }
994 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000995}
996
997static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000998bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000999{
1000 Py_ssize_t self_size, other_size;
1001 Py_buffer self_bytes, other_bytes;
1002 PyObject *res;
1003 Py_ssize_t minsize;
1004 int cmp;
1005
1006 /* Bytes can be compared to anything that supports the (binary)
1007 buffer API. Except that a comparison with Unicode is always an
1008 error, even if the comparison is for equality. */
1009 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1010 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +00001011 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001012 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +00001013 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001014 return NULL;
1015 }
1016
Brian Curtindfc80e32011-08-10 20:28:54 -05001017 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001018 }
1019
1020 self_size = _getbuffer(self, &self_bytes);
1021 if (self_size < 0) {
1022 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -05001023 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001024 }
1025
1026 other_size = _getbuffer(other, &other_bytes);
1027 if (other_size < 0) {
1028 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001029 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001030 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001031 }
1032
1033 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1034 /* Shortcut: if the lengths differ, the objects differ */
1035 cmp = (op == Py_NE);
1036 }
1037 else {
1038 minsize = self_size;
1039 if (other_size < minsize)
1040 minsize = other_size;
1041
1042 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1043 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1044
1045 if (cmp == 0) {
1046 if (self_size < other_size)
1047 cmp = -1;
1048 else if (self_size > other_size)
1049 cmp = 1;
1050 }
1051
1052 switch (op) {
1053 case Py_LT: cmp = cmp < 0; break;
1054 case Py_LE: cmp = cmp <= 0; break;
1055 case Py_EQ: cmp = cmp == 0; break;
1056 case Py_NE: cmp = cmp != 0; break;
1057 case Py_GT: cmp = cmp > 0; break;
1058 case Py_GE: cmp = cmp >= 0; break;
1059 }
1060 }
1061
1062 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001063 PyBuffer_Release(&self_bytes);
1064 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001065 Py_INCREF(res);
1066 return res;
1067}
1068
1069static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001070bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001071{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001072 if (self->ob_exports > 0) {
1073 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001074 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001075 PyErr_Print();
1076 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001077 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001078 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001079 }
1080 Py_TYPE(self)->tp_free((PyObject *)self);
1081}
1082
1083
1084/* -------------------------------------------------------------------- */
1085/* Methods */
1086
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001087#define FASTSEARCH fastsearch
1088#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001089#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001090#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001091#define STRINGLIB_LEN PyByteArray_GET_SIZE
1092#define STRINGLIB_STR PyByteArray_AS_STRING
1093#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001094#define STRINGLIB_ISSPACE Py_ISSPACE
1095#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001096#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1097#define STRINGLIB_MUTABLE 1
1098
1099#include "stringlib/fastsearch.h"
1100#include "stringlib/count.h"
1101#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001102#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001103#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001104#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001105#include "stringlib/ctype.h"
1106#include "stringlib/transmogrify.h"
1107
1108
1109/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1110were copied from the old char* style string object. */
1111
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001112/* helper macro to fixup start/end slice values */
1113#define ADJUST_INDICES(start, end, len) \
1114 if (end > len) \
1115 end = len; \
1116 else if (end < 0) { \
1117 end += len; \
1118 if (end < 0) \
1119 end = 0; \
1120 } \
1121 if (start < 0) { \
1122 start += len; \
1123 if (start < 0) \
1124 start = 0; \
1125 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001126
1127Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001128bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001129{
1130 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001131 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001132 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001133 const char *sub;
1134 Py_ssize_t sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001135 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1136 Py_ssize_t res;
1137
Antoine Pitrouac65d962011-10-20 23:54:17 +02001138 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1139 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001140 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001141
1142 if (subobj) {
1143 if (_getbuffer(subobj, &subbuf) < 0)
1144 return -2;
1145
1146 sub = subbuf.buf;
1147 sub_len = subbuf.len;
1148 }
1149 else {
1150 sub = &byte;
1151 sub_len = 1;
1152 }
1153
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001154 if (dir > 0)
1155 res = stringlib_find_slice(
1156 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001157 sub, sub_len, start, end);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001158 else
1159 res = stringlib_rfind_slice(
1160 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001161 sub, sub_len, start, end);
1162
1163 if (subobj)
1164 PyBuffer_Release(&subbuf);
1165
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001166 return res;
1167}
1168
1169PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001170"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001171\n\
1172Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001173such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001174arguments start and end are interpreted as in slice notation.\n\
1175\n\
1176Return -1 on failure.");
1177
1178static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001179bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001180{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001181 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001182 if (result == -2)
1183 return NULL;
1184 return PyLong_FromSsize_t(result);
1185}
1186
1187PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001188"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001189\n\
1190Return the number of non-overlapping occurrences of subsection sub in\n\
1191bytes B[start:end]. Optional arguments start and end are interpreted\n\
1192as in slice notation.");
1193
1194static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001195bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001196{
1197 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001198 const char *str = PyByteArray_AS_STRING(self), *sub;
1199 Py_ssize_t sub_len;
1200 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001201 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001202
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001203 Py_buffer vsub;
1204 PyObject *count_obj;
1205
Antoine Pitrouac65d962011-10-20 23:54:17 +02001206 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1207 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001208 return NULL;
1209
Antoine Pitrouac65d962011-10-20 23:54:17 +02001210 if (sub_obj) {
1211 if (_getbuffer(sub_obj, &vsub) < 0)
1212 return NULL;
1213
1214 sub = vsub.buf;
1215 sub_len = vsub.len;
1216 }
1217 else {
1218 sub = &byte;
1219 sub_len = 1;
1220 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001221
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001222 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001223
1224 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001225 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001226 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001227
1228 if (sub_obj)
1229 PyBuffer_Release(&vsub);
1230
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001231 return count_obj;
1232}
1233
Eli Bendersky4db28d32011-03-03 18:21:02 +00001234PyDoc_STRVAR(clear__doc__,
1235"B.clear() -> None\n\
1236\n\
1237Remove all items from B.");
1238
Victor Stinner6430fd52011-09-29 04:02:13 +02001239static PyObject *
Eli Bendersky4db28d32011-03-03 18:21:02 +00001240bytearray_clear(PyByteArrayObject *self)
1241{
1242 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1243 return NULL;
1244 Py_RETURN_NONE;
1245}
1246
1247PyDoc_STRVAR(copy__doc__,
1248"B.copy() -> bytearray\n\
1249\n\
1250Return a copy of B.");
1251
1252static PyObject *
1253bytearray_copy(PyByteArrayObject *self)
1254{
1255 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1256 PyByteArray_GET_SIZE(self));
1257}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001258
1259PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001260"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001261\n\
1262Like B.find() but raise ValueError when the subsection is not found.");
1263
1264static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001265bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001266{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001267 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001268 if (result == -2)
1269 return NULL;
1270 if (result == -1) {
1271 PyErr_SetString(PyExc_ValueError,
1272 "subsection not found");
1273 return NULL;
1274 }
1275 return PyLong_FromSsize_t(result);
1276}
1277
1278
1279PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001280"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001281\n\
1282Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001283such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001284arguments start and end are interpreted as in slice notation.\n\
1285\n\
1286Return -1 on failure.");
1287
1288static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001289bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001290{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001291 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001292 if (result == -2)
1293 return NULL;
1294 return PyLong_FromSsize_t(result);
1295}
1296
1297
1298PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001299"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001300\n\
1301Like B.rfind() but raise ValueError when the subsection is not found.");
1302
1303static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001304bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001305{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001306 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001307 if (result == -2)
1308 return NULL;
1309 if (result == -1) {
1310 PyErr_SetString(PyExc_ValueError,
1311 "subsection not found");
1312 return NULL;
1313 }
1314 return PyLong_FromSsize_t(result);
1315}
1316
1317
1318static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001319bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001320{
1321 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1322 if (ival == -1 && PyErr_Occurred()) {
1323 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001324 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001325 PyErr_Clear();
1326 if (_getbuffer(arg, &varg) < 0)
1327 return -1;
1328 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1329 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001330 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001331 return pos >= 0;
1332 }
1333 if (ival < 0 || ival >= 256) {
1334 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1335 return -1;
1336 }
1337
Antoine Pitrou0010d372010-08-15 17:12:55 +00001338 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001339}
1340
1341
1342/* Matches the end (direction >= 0) or start (direction < 0) of self
1343 * against substr, using the start and end arguments. Returns
1344 * -1 on error, 0 if not found and 1 if found.
1345 */
1346Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001347_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001348 Py_ssize_t end, int direction)
1349{
1350 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1351 const char* str;
1352 Py_buffer vsubstr;
1353 int rv = 0;
1354
1355 str = PyByteArray_AS_STRING(self);
1356
1357 if (_getbuffer(substr, &vsubstr) < 0)
1358 return -1;
1359
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001360 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001361
1362 if (direction < 0) {
1363 /* startswith */
1364 if (start+vsubstr.len > len) {
1365 goto done;
1366 }
1367 } else {
1368 /* endswith */
1369 if (end-start < vsubstr.len || start > len) {
1370 goto done;
1371 }
1372
1373 if (end-vsubstr.len > start)
1374 start = end - vsubstr.len;
1375 }
1376 if (end-start >= vsubstr.len)
1377 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1378
1379done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001380 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001381 return rv;
1382}
1383
1384
1385PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001386"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001387\n\
1388Return True if B starts with the specified prefix, False otherwise.\n\
1389With optional start, test B beginning at that position.\n\
1390With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001391prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001392
1393static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001394bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001395{
1396 Py_ssize_t start = 0;
1397 Py_ssize_t end = PY_SSIZE_T_MAX;
1398 PyObject *subobj;
1399 int result;
1400
Jesus Ceaac451502011-04-20 17:09:23 +02001401 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001402 return NULL;
1403 if (PyTuple_Check(subobj)) {
1404 Py_ssize_t i;
1405 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001406 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001407 PyTuple_GET_ITEM(subobj, i),
1408 start, end, -1);
1409 if (result == -1)
1410 return NULL;
1411 else if (result) {
1412 Py_RETURN_TRUE;
1413 }
1414 }
1415 Py_RETURN_FALSE;
1416 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001417 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001418 if (result == -1) {
1419 if (PyErr_ExceptionMatches(PyExc_TypeError))
1420 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1421 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001422 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001423 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001424 else
1425 return PyBool_FromLong(result);
1426}
1427
1428PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001429"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001430\n\
1431Return True if B ends with the specified suffix, False otherwise.\n\
1432With optional start, test B beginning at that position.\n\
1433With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001434suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001435
1436static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001437bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001438{
1439 Py_ssize_t start = 0;
1440 Py_ssize_t end = PY_SSIZE_T_MAX;
1441 PyObject *subobj;
1442 int result;
1443
Jesus Ceaac451502011-04-20 17:09:23 +02001444 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001445 return NULL;
1446 if (PyTuple_Check(subobj)) {
1447 Py_ssize_t i;
1448 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001449 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001450 PyTuple_GET_ITEM(subobj, i),
1451 start, end, +1);
1452 if (result == -1)
1453 return NULL;
1454 else if (result) {
1455 Py_RETURN_TRUE;
1456 }
1457 }
1458 Py_RETURN_FALSE;
1459 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001460 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001461 if (result == -1) {
1462 if (PyErr_ExceptionMatches(PyExc_TypeError))
1463 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1464 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001465 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001466 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001467 else
1468 return PyBool_FromLong(result);
1469}
1470
1471
1472PyDoc_STRVAR(translate__doc__,
1473"B.translate(table[, deletechars]) -> bytearray\n\
1474\n\
1475Return a copy of B, where all characters occurring in the\n\
1476optional argument deletechars are removed, and the remaining\n\
1477characters have been mapped through the given translation\n\
1478table, which must be a bytes object of length 256.");
1479
1480static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001481bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001482{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001483 char *input, *output;
1484 const char *table;
1485 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001486 PyObject *input_obj = (PyObject*)self;
1487 const char *output_start;
1488 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001489 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001490 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001491 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001492 Py_buffer vtable, vdel;
1493
1494 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1495 &tableobj, &delobj))
1496 return NULL;
1497
Georg Brandlccc47b62008-12-28 11:44:14 +00001498 if (tableobj == Py_None) {
1499 table = NULL;
1500 tableobj = NULL;
1501 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001502 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001503 } else {
1504 if (vtable.len != 256) {
1505 PyErr_SetString(PyExc_ValueError,
1506 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001507 PyBuffer_Release(&vtable);
1508 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001509 }
1510 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001511 }
1512
1513 if (delobj != NULL) {
1514 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001515 if (tableobj != NULL)
1516 PyBuffer_Release(&vtable);
1517 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001518 }
1519 }
1520 else {
1521 vdel.buf = NULL;
1522 vdel.len = 0;
1523 }
1524
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001525 inlen = PyByteArray_GET_SIZE(input_obj);
1526 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1527 if (result == NULL)
1528 goto done;
1529 output_start = output = PyByteArray_AsString(result);
1530 input = PyByteArray_AS_STRING(input_obj);
1531
Georg Brandlccc47b62008-12-28 11:44:14 +00001532 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001533 /* If no deletions are required, use faster code */
1534 for (i = inlen; --i >= 0; ) {
1535 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001536 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001537 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001538 goto done;
1539 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001540
1541 if (table == NULL) {
1542 for (i = 0; i < 256; i++)
1543 trans_table[i] = Py_CHARMASK(i);
1544 } else {
1545 for (i = 0; i < 256; i++)
1546 trans_table[i] = Py_CHARMASK(table[i]);
1547 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001548
1549 for (i = 0; i < vdel.len; i++)
1550 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1551
1552 for (i = inlen; --i >= 0; ) {
1553 c = Py_CHARMASK(*input++);
1554 if (trans_table[c] != -1)
1555 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1556 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001557 }
1558 /* Fix the size of the resulting string */
1559 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001560 if (PyByteArray_Resize(result, output - output_start) < 0) {
1561 Py_CLEAR(result);
1562 goto done;
1563 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001564
1565done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001566 if (tableobj != NULL)
1567 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001568 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001569 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001570 return result;
1571}
1572
1573
Georg Brandlabc38772009-04-12 15:51:51 +00001574static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001575bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001576{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001577 return _Py_bytes_maketrans(args);
Georg Brandlabc38772009-04-12 15:51:51 +00001578}
1579
1580
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001581/* find and count characters and substrings */
1582
1583#define findchar(target, target_len, c) \
1584 ((char *)memchr((const void *)(target), c, target_len))
1585
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001586
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001587/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001588Py_LOCAL(PyByteArrayObject *)
1589return_self(PyByteArrayObject *self)
1590{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001591 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001592 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1593 PyByteArray_AS_STRING(self),
1594 PyByteArray_GET_SIZE(self));
1595}
1596
1597Py_LOCAL_INLINE(Py_ssize_t)
1598countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1599{
1600 Py_ssize_t count=0;
1601 const char *start=target;
1602 const char *end=target+target_len;
1603
1604 while ( (start=findchar(start, end-start, c)) != NULL ) {
1605 count++;
1606 if (count >= maxcount)
1607 break;
1608 start += 1;
1609 }
1610 return count;
1611}
1612
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001613
1614/* Algorithms for different cases of string replacement */
1615
1616/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1617Py_LOCAL(PyByteArrayObject *)
1618replace_interleave(PyByteArrayObject *self,
1619 const char *to_s, Py_ssize_t to_len,
1620 Py_ssize_t maxcount)
1621{
1622 char *self_s, *result_s;
1623 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001624 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001625 PyByteArrayObject *result;
1626
1627 self_len = PyByteArray_GET_SIZE(self);
1628
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001629 /* 1 at the end plus 1 after every character;
1630 count = min(maxcount, self_len + 1) */
1631 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001632 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001633 else
1634 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1635 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001636
1637 /* Check for overflow */
1638 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001639 assert(count > 0);
1640 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001641 PyErr_SetString(PyExc_OverflowError,
1642 "replace string is too long");
1643 return NULL;
1644 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001645 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001646
1647 if (! (result = (PyByteArrayObject *)
1648 PyByteArray_FromStringAndSize(NULL, result_len)) )
1649 return NULL;
1650
1651 self_s = PyByteArray_AS_STRING(self);
1652 result_s = PyByteArray_AS_STRING(result);
1653
1654 /* TODO: special case single character, which doesn't need memcpy */
1655
1656 /* Lay the first one down (guaranteed this will occur) */
1657 Py_MEMCPY(result_s, to_s, to_len);
1658 result_s += to_len;
1659 count -= 1;
1660
1661 for (i=0; i<count; i++) {
1662 *result_s++ = *self_s++;
1663 Py_MEMCPY(result_s, to_s, to_len);
1664 result_s += to_len;
1665 }
1666
1667 /* Copy the rest of the original string */
1668 Py_MEMCPY(result_s, self_s, self_len-i);
1669
1670 return result;
1671}
1672
1673/* Special case for deleting a single character */
1674/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1675Py_LOCAL(PyByteArrayObject *)
1676replace_delete_single_character(PyByteArrayObject *self,
1677 char from_c, Py_ssize_t maxcount)
1678{
1679 char *self_s, *result_s;
1680 char *start, *next, *end;
1681 Py_ssize_t self_len, result_len;
1682 Py_ssize_t count;
1683 PyByteArrayObject *result;
1684
1685 self_len = PyByteArray_GET_SIZE(self);
1686 self_s = PyByteArray_AS_STRING(self);
1687
1688 count = countchar(self_s, self_len, from_c, maxcount);
1689 if (count == 0) {
1690 return return_self(self);
1691 }
1692
1693 result_len = self_len - count; /* from_len == 1 */
1694 assert(result_len>=0);
1695
1696 if ( (result = (PyByteArrayObject *)
1697 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1698 return NULL;
1699 result_s = PyByteArray_AS_STRING(result);
1700
1701 start = self_s;
1702 end = self_s + self_len;
1703 while (count-- > 0) {
1704 next = findchar(start, end-start, from_c);
1705 if (next == NULL)
1706 break;
1707 Py_MEMCPY(result_s, start, next-start);
1708 result_s += (next-start);
1709 start = next+1;
1710 }
1711 Py_MEMCPY(result_s, start, end-start);
1712
1713 return result;
1714}
1715
1716/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1717
1718Py_LOCAL(PyByteArrayObject *)
1719replace_delete_substring(PyByteArrayObject *self,
1720 const char *from_s, Py_ssize_t from_len,
1721 Py_ssize_t maxcount)
1722{
1723 char *self_s, *result_s;
1724 char *start, *next, *end;
1725 Py_ssize_t self_len, result_len;
1726 Py_ssize_t count, offset;
1727 PyByteArrayObject *result;
1728
1729 self_len = PyByteArray_GET_SIZE(self);
1730 self_s = PyByteArray_AS_STRING(self);
1731
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001732 count = stringlib_count(self_s, self_len,
1733 from_s, from_len,
1734 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001735
1736 if (count == 0) {
1737 /* no matches */
1738 return return_self(self);
1739 }
1740
1741 result_len = self_len - (count * from_len);
1742 assert (result_len>=0);
1743
1744 if ( (result = (PyByteArrayObject *)
1745 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1746 return NULL;
1747
1748 result_s = PyByteArray_AS_STRING(result);
1749
1750 start = self_s;
1751 end = self_s + self_len;
1752 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001753 offset = stringlib_find(start, end-start,
1754 from_s, from_len,
1755 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001756 if (offset == -1)
1757 break;
1758 next = start + offset;
1759
1760 Py_MEMCPY(result_s, start, next-start);
1761
1762 result_s += (next-start);
1763 start = next+from_len;
1764 }
1765 Py_MEMCPY(result_s, start, end-start);
1766 return result;
1767}
1768
1769/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1770Py_LOCAL(PyByteArrayObject *)
1771replace_single_character_in_place(PyByteArrayObject *self,
1772 char from_c, char to_c,
1773 Py_ssize_t maxcount)
1774{
Antoine Pitroud1188562010-06-09 16:38:55 +00001775 char *self_s, *result_s, *start, *end, *next;
1776 Py_ssize_t self_len;
1777 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001778
Antoine Pitroud1188562010-06-09 16:38:55 +00001779 /* The result string will be the same size */
1780 self_s = PyByteArray_AS_STRING(self);
1781 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001782
Antoine Pitroud1188562010-06-09 16:38:55 +00001783 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001784
Antoine Pitroud1188562010-06-09 16:38:55 +00001785 if (next == NULL) {
1786 /* No matches; return the original bytes */
1787 return return_self(self);
1788 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001789
Antoine Pitroud1188562010-06-09 16:38:55 +00001790 /* Need to make a new bytes */
1791 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1792 if (result == NULL)
1793 return NULL;
1794 result_s = PyByteArray_AS_STRING(result);
1795 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001796
Antoine Pitroud1188562010-06-09 16:38:55 +00001797 /* change everything in-place, starting with this one */
1798 start = result_s + (next-self_s);
1799 *start = to_c;
1800 start++;
1801 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001802
Antoine Pitroud1188562010-06-09 16:38:55 +00001803 while (--maxcount > 0) {
1804 next = findchar(start, end-start, from_c);
1805 if (next == NULL)
1806 break;
1807 *next = to_c;
1808 start = next+1;
1809 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001810
Antoine Pitroud1188562010-06-09 16:38:55 +00001811 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001812}
1813
1814/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1815Py_LOCAL(PyByteArrayObject *)
1816replace_substring_in_place(PyByteArrayObject *self,
1817 const char *from_s, Py_ssize_t from_len,
1818 const char *to_s, Py_ssize_t to_len,
1819 Py_ssize_t maxcount)
1820{
1821 char *result_s, *start, *end;
1822 char *self_s;
1823 Py_ssize_t self_len, offset;
1824 PyByteArrayObject *result;
1825
1826 /* The result bytes will be the same size */
1827
1828 self_s = PyByteArray_AS_STRING(self);
1829 self_len = PyByteArray_GET_SIZE(self);
1830
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001831 offset = stringlib_find(self_s, self_len,
1832 from_s, from_len,
1833 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001834 if (offset == -1) {
1835 /* No matches; return the original bytes */
1836 return return_self(self);
1837 }
1838
1839 /* Need to make a new bytes */
1840 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1841 if (result == NULL)
1842 return NULL;
1843 result_s = PyByteArray_AS_STRING(result);
1844 Py_MEMCPY(result_s, self_s, self_len);
1845
1846 /* change everything in-place, starting with this one */
1847 start = result_s + offset;
1848 Py_MEMCPY(start, to_s, from_len);
1849 start += from_len;
1850 end = result_s + self_len;
1851
1852 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001853 offset = stringlib_find(start, end-start,
1854 from_s, from_len,
1855 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001856 if (offset==-1)
1857 break;
1858 Py_MEMCPY(start+offset, to_s, from_len);
1859 start += offset+from_len;
1860 }
1861
1862 return result;
1863}
1864
1865/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1866Py_LOCAL(PyByteArrayObject *)
1867replace_single_character(PyByteArrayObject *self,
1868 char from_c,
1869 const char *to_s, Py_ssize_t to_len,
1870 Py_ssize_t maxcount)
1871{
1872 char *self_s, *result_s;
1873 char *start, *next, *end;
1874 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001875 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001876 PyByteArrayObject *result;
1877
1878 self_s = PyByteArray_AS_STRING(self);
1879 self_len = PyByteArray_GET_SIZE(self);
1880
1881 count = countchar(self_s, self_len, from_c, maxcount);
1882 if (count == 0) {
1883 /* no matches, return unchanged */
1884 return return_self(self);
1885 }
1886
1887 /* use the difference between current and new, hence the "-1" */
1888 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001889 assert(count > 0);
1890 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001891 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1892 return NULL;
1893 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001894 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001895
1896 if ( (result = (PyByteArrayObject *)
1897 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1898 return NULL;
1899 result_s = PyByteArray_AS_STRING(result);
1900
1901 start = self_s;
1902 end = self_s + self_len;
1903 while (count-- > 0) {
1904 next = findchar(start, end-start, from_c);
1905 if (next == NULL)
1906 break;
1907
1908 if (next == start) {
1909 /* replace with the 'to' */
1910 Py_MEMCPY(result_s, to_s, to_len);
1911 result_s += to_len;
1912 start += 1;
1913 } else {
1914 /* copy the unchanged old then the 'to' */
1915 Py_MEMCPY(result_s, start, next-start);
1916 result_s += (next-start);
1917 Py_MEMCPY(result_s, to_s, to_len);
1918 result_s += to_len;
1919 start = next+1;
1920 }
1921 }
1922 /* Copy the remainder of the remaining bytes */
1923 Py_MEMCPY(result_s, start, end-start);
1924
1925 return result;
1926}
1927
1928/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1929Py_LOCAL(PyByteArrayObject *)
1930replace_substring(PyByteArrayObject *self,
1931 const char *from_s, Py_ssize_t from_len,
1932 const char *to_s, Py_ssize_t to_len,
1933 Py_ssize_t maxcount)
1934{
1935 char *self_s, *result_s;
1936 char *start, *next, *end;
1937 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001938 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001939 PyByteArrayObject *result;
1940
1941 self_s = PyByteArray_AS_STRING(self);
1942 self_len = PyByteArray_GET_SIZE(self);
1943
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001944 count = stringlib_count(self_s, self_len,
1945 from_s, from_len,
1946 maxcount);
1947
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001948 if (count == 0) {
1949 /* no matches, return unchanged */
1950 return return_self(self);
1951 }
1952
1953 /* Check for overflow */
1954 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001955 assert(count > 0);
1956 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001957 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1958 return NULL;
1959 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001960 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001961
1962 if ( (result = (PyByteArrayObject *)
1963 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1964 return NULL;
1965 result_s = PyByteArray_AS_STRING(result);
1966
1967 start = self_s;
1968 end = self_s + self_len;
1969 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001970 offset = stringlib_find(start, end-start,
1971 from_s, from_len,
1972 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001973 if (offset == -1)
1974 break;
1975 next = start+offset;
1976 if (next == start) {
1977 /* replace with the 'to' */
1978 Py_MEMCPY(result_s, to_s, to_len);
1979 result_s += to_len;
1980 start += from_len;
1981 } else {
1982 /* copy the unchanged old then the 'to' */
1983 Py_MEMCPY(result_s, start, next-start);
1984 result_s += (next-start);
1985 Py_MEMCPY(result_s, to_s, to_len);
1986 result_s += to_len;
1987 start = next+from_len;
1988 }
1989 }
1990 /* Copy the remainder of the remaining bytes */
1991 Py_MEMCPY(result_s, start, end-start);
1992
1993 return result;
1994}
1995
1996
1997Py_LOCAL(PyByteArrayObject *)
1998replace(PyByteArrayObject *self,
1999 const char *from_s, Py_ssize_t from_len,
2000 const char *to_s, Py_ssize_t to_len,
2001 Py_ssize_t maxcount)
2002{
2003 if (maxcount < 0) {
2004 maxcount = PY_SSIZE_T_MAX;
2005 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
2006 /* nothing to do; return the original bytes */
2007 return return_self(self);
2008 }
2009
2010 if (maxcount == 0 ||
2011 (from_len == 0 && to_len == 0)) {
2012 /* nothing to do; return the original bytes */
2013 return return_self(self);
2014 }
2015
2016 /* Handle zero-length special cases */
2017
2018 if (from_len == 0) {
2019 /* insert the 'to' bytes everywhere. */
2020 /* >>> "Python".replace("", ".") */
2021 /* '.P.y.t.h.o.n.' */
2022 return replace_interleave(self, to_s, to_len, maxcount);
2023 }
2024
2025 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2026 /* point for an empty self bytes to generate a non-empty bytes */
2027 /* Special case so the remaining code always gets a non-empty bytes */
2028 if (PyByteArray_GET_SIZE(self) == 0) {
2029 return return_self(self);
2030 }
2031
2032 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002033 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002034 if (from_len == 1) {
2035 return replace_delete_single_character(
2036 self, from_s[0], maxcount);
2037 } else {
2038 return replace_delete_substring(self, from_s, from_len, maxcount);
2039 }
2040 }
2041
2042 /* Handle special case where both bytes have the same length */
2043
2044 if (from_len == to_len) {
2045 if (from_len == 1) {
2046 return replace_single_character_in_place(
2047 self,
2048 from_s[0],
2049 to_s[0],
2050 maxcount);
2051 } else {
2052 return replace_substring_in_place(
2053 self, from_s, from_len, to_s, to_len, maxcount);
2054 }
2055 }
2056
2057 /* Otherwise use the more generic algorithms */
2058 if (from_len == 1) {
2059 return replace_single_character(self, from_s[0],
2060 to_s, to_len, maxcount);
2061 } else {
2062 /* len('from')>=2, len('to')>=1 */
2063 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2064 }
2065}
2066
2067
2068PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002069"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002070\n\
2071Return a copy of B with all occurrences of subsection\n\
2072old replaced by new. If the optional argument count is\n\
2073given, only the first count occurrences are replaced.");
2074
2075static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002076bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002077{
2078 Py_ssize_t count = -1;
2079 PyObject *from, *to, *res;
2080 Py_buffer vfrom, vto;
2081
2082 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2083 return NULL;
2084
2085 if (_getbuffer(from, &vfrom) < 0)
2086 return NULL;
2087 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +00002088 PyBuffer_Release(&vfrom);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002089 return NULL;
2090 }
2091
2092 res = (PyObject *)replace((PyByteArrayObject *) self,
2093 vfrom.buf, vfrom.len,
2094 vto.buf, vto.len, count);
2095
Martin v. Löwis423be952008-08-13 15:53:07 +00002096 PyBuffer_Release(&vfrom);
2097 PyBuffer_Release(&vto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002098 return res;
2099}
2100
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002101PyDoc_STRVAR(split__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002102"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002103\n\
2104Return a list of the sections in B, using sep as the delimiter.\n\
2105If sep is not given, B is split on ASCII whitespace characters\n\
2106(space, tab, return, newline, formfeed, vertical tab).\n\
2107If maxsplit is given, at most maxsplit splits are done.");
2108
2109static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002110bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002111{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002112 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002113 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2114 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002115 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002116 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002117 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002118
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002119 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
2120 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002121 return NULL;
2122 if (maxsplit < 0)
2123 maxsplit = PY_SSIZE_T_MAX;
2124
2125 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002126 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002127
2128 if (_getbuffer(subobj, &vsub) < 0)
2129 return NULL;
2130 sub = vsub.buf;
2131 n = vsub.len;
2132
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002133 list = stringlib_split(
2134 (PyObject*) self, s, len, sub, n, maxsplit
2135 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002136 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002137 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002138}
2139
2140PyDoc_STRVAR(partition__doc__,
2141"B.partition(sep) -> (head, sep, tail)\n\
2142\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002143Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002144the separator itself, and the part after it. If the separator is not\n\
2145found, returns B and two empty bytearray objects.");
2146
2147static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002148bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002149{
2150 PyObject *bytesep, *result;
2151
2152 bytesep = PyByteArray_FromObject(sep_obj);
2153 if (! bytesep)
2154 return NULL;
2155
2156 result = stringlib_partition(
2157 (PyObject*) self,
2158 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2159 bytesep,
2160 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2161 );
2162
2163 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002164 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002165}
2166
2167PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002168"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002169\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002170Search for the separator sep in B, starting at the end of B,\n\
2171and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002172part after it. If the separator is not found, returns two empty\n\
2173bytearray objects and B.");
2174
2175static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002176bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002177{
2178 PyObject *bytesep, *result;
2179
2180 bytesep = PyByteArray_FromObject(sep_obj);
2181 if (! bytesep)
2182 return NULL;
2183
2184 result = stringlib_rpartition(
2185 (PyObject*) self,
2186 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2187 bytesep,
2188 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2189 );
2190
2191 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002192 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002193}
2194
2195PyDoc_STRVAR(rsplit__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002196"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002197\n\
2198Return a list of the sections in B, using sep as the delimiter,\n\
2199starting at the end of B and working to the front.\n\
2200If sep is not given, B is split on ASCII whitespace characters\n\
2201(space, tab, return, newline, formfeed, vertical tab).\n\
2202If maxsplit is given, at most maxsplit splits are done.");
2203
2204static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002205bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002206{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002207 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002208 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2209 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002210 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002211 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002212 Py_buffer vsub;
2213
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002214 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit",
2215 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002216 return NULL;
2217 if (maxsplit < 0)
2218 maxsplit = PY_SSIZE_T_MAX;
2219
2220 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002221 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002222
2223 if (_getbuffer(subobj, &vsub) < 0)
2224 return NULL;
2225 sub = vsub.buf;
2226 n = vsub.len;
2227
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002228 list = stringlib_rsplit(
2229 (PyObject*) self, s, len, sub, n, maxsplit
2230 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002231 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002232 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002233}
2234
2235PyDoc_STRVAR(reverse__doc__,
2236"B.reverse() -> None\n\
2237\n\
2238Reverse the order of the values in B in place.");
2239static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002240bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002241{
2242 char swap, *head, *tail;
2243 Py_ssize_t i, j, n = Py_SIZE(self);
2244
2245 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002246 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002247 tail = head + n - 1;
2248 for (i = 0; i < j; i++) {
2249 swap = *head;
2250 *head++ = *tail;
2251 *tail-- = swap;
2252 }
2253
2254 Py_RETURN_NONE;
2255}
2256
2257PyDoc_STRVAR(insert__doc__,
2258"B.insert(index, int) -> None\n\
2259\n\
2260Insert a single item into the bytearray before the given index.");
2261static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002262bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002263{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002264 PyObject *value;
2265 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002266 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002267 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002268
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002269 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002270 return NULL;
2271
2272 if (n == PY_SSIZE_T_MAX) {
2273 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002274 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002275 return NULL;
2276 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002277 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002278 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002279 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2280 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002281 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002282
2283 if (where < 0) {
2284 where += n;
2285 if (where < 0)
2286 where = 0;
2287 }
2288 if (where > n)
2289 where = n;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002290 memmove(buf + where + 1, buf + where, n - where);
2291 buf[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002292
2293 Py_RETURN_NONE;
2294}
2295
2296PyDoc_STRVAR(append__doc__,
2297"B.append(int) -> None\n\
2298\n\
2299Append a single item to the end of B.");
2300static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002301bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002302{
2303 int value;
2304 Py_ssize_t n = Py_SIZE(self);
2305
2306 if (! _getbytevalue(arg, &value))
2307 return NULL;
2308 if (n == PY_SSIZE_T_MAX) {
2309 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002310 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002311 return NULL;
2312 }
2313 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2314 return NULL;
2315
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002316 PyByteArray_AS_STRING(self)[n] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002317
2318 Py_RETURN_NONE;
2319}
2320
2321PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002322"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002323\n\
2324Append all the elements from the iterator or sequence to the\n\
2325end of B.");
2326static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002327bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002328{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002329 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002330 Py_ssize_t buf_size = 0, len = 0;
2331 int value;
2332 char *buf;
2333
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002334 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002335 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002336 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002337 return NULL;
2338
2339 Py_RETURN_NONE;
2340 }
2341
2342 it = PyObject_GetIter(arg);
2343 if (it == NULL)
2344 return NULL;
2345
Ezio Melotti42da6632011-03-15 05:18:48 +02002346 /* Try to determine the length of the argument. 32 is arbitrary. */
Armin Ronacheraa9a79d2012-10-06 14:03:24 +02002347 buf_size = PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002348 if (buf_size == -1) {
2349 Py_DECREF(it);
2350 return NULL;
2351 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002352
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002353 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002354 if (bytearray_obj == NULL) {
2355 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002356 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002357 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002358 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002359
2360 while ((item = PyIter_Next(it)) != NULL) {
2361 if (! _getbytevalue(item, &value)) {
2362 Py_DECREF(item);
2363 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002364 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002365 return NULL;
2366 }
2367 buf[len++] = value;
2368 Py_DECREF(item);
2369
2370 if (len >= buf_size) {
2371 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002372 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002373 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002374 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002375 return NULL;
2376 }
2377 /* Recompute the `buf' pointer, since the resizing operation may
2378 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002379 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002380 }
2381 }
2382 Py_DECREF(it);
2383
2384 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002385 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2386 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002387 return NULL;
2388 }
2389
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002390 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2391 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002392 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002393 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002394 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002395
2396 Py_RETURN_NONE;
2397}
2398
2399PyDoc_STRVAR(pop__doc__,
2400"B.pop([index]) -> int\n\
2401\n\
2402Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002403argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002404static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002405bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002406{
2407 int value;
2408 Py_ssize_t where = -1, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002409 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002410
2411 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2412 return NULL;
2413
2414 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002415 PyErr_SetString(PyExc_IndexError,
2416 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002417 return NULL;
2418 }
2419 if (where < 0)
2420 where += Py_SIZE(self);
2421 if (where < 0 || where >= Py_SIZE(self)) {
2422 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2423 return NULL;
2424 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002425 if (!_canresize(self))
2426 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002427
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002428 buf = PyByteArray_AS_STRING(self);
2429 value = buf[where];
2430 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002431 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2432 return NULL;
2433
Mark Dickinson54a3db92009-09-06 10:19:23 +00002434 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002435}
2436
2437PyDoc_STRVAR(remove__doc__,
2438"B.remove(int) -> None\n\
2439\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002440Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002441static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002442bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002443{
2444 int value;
2445 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002446 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002447
2448 if (! _getbytevalue(arg, &value))
2449 return NULL;
2450
2451 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002452 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002453 break;
2454 }
2455 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002456 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002457 return NULL;
2458 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002459 if (!_canresize(self))
2460 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002461
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002462 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002463 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2464 return NULL;
2465
2466 Py_RETURN_NONE;
2467}
2468
2469/* XXX These two helpers could be optimized if argsize == 1 */
2470
2471static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002472lstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002473 void *argptr, Py_ssize_t argsize)
2474{
2475 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002476 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002477 i++;
2478 return i;
2479}
2480
2481static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002482rstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002483 void *argptr, Py_ssize_t argsize)
2484{
2485 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002486 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002487 i--;
2488 return i + 1;
2489}
2490
2491PyDoc_STRVAR(strip__doc__,
2492"B.strip([bytes]) -> bytearray\n\
2493\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002494Strip leading and trailing bytes contained in the argument\n\
2495and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002496If the argument is omitted, strip ASCII whitespace.");
2497static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002498bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002499{
2500 Py_ssize_t left, right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002501 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002502 PyObject *arg = Py_None;
2503 Py_buffer varg;
2504 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2505 return NULL;
2506 if (arg == Py_None) {
2507 argptr = "\t\n\r\f\v ";
2508 argsize = 6;
2509 }
2510 else {
2511 if (_getbuffer(arg, &varg) < 0)
2512 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002513 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002514 argsize = varg.len;
2515 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002516 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002517 mysize = Py_SIZE(self);
2518 left = lstrip_helper(myptr, mysize, argptr, argsize);
2519 if (left == mysize)
2520 right = left;
2521 else
2522 right = rstrip_helper(myptr, mysize, argptr, argsize);
2523 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002524 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002525 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002526}
2527
2528PyDoc_STRVAR(lstrip__doc__,
2529"B.lstrip([bytes]) -> bytearray\n\
2530\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002531Strip leading bytes contained in the argument\n\
2532and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002533If the argument is omitted, strip leading ASCII whitespace.");
2534static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002535bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002536{
2537 Py_ssize_t left, right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002538 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002539 PyObject *arg = Py_None;
2540 Py_buffer varg;
2541 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2542 return NULL;
2543 if (arg == Py_None) {
2544 argptr = "\t\n\r\f\v ";
2545 argsize = 6;
2546 }
2547 else {
2548 if (_getbuffer(arg, &varg) < 0)
2549 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002550 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002551 argsize = varg.len;
2552 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002553 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002554 mysize = Py_SIZE(self);
2555 left = lstrip_helper(myptr, mysize, argptr, argsize);
2556 right = mysize;
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 + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002560}
2561
2562PyDoc_STRVAR(rstrip__doc__,
2563"B.rstrip([bytes]) -> bytearray\n\
2564\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002565Strip trailing bytes contained in the argument\n\
2566and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002567If the argument is omitted, strip trailing ASCII whitespace.");
2568static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002569bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002570{
Brett Cannonb94767f2011-02-22 20:15:44 +00002571 Py_ssize_t right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002572 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002573 PyObject *arg = Py_None;
2574 Py_buffer varg;
2575 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2576 return NULL;
2577 if (arg == Py_None) {
2578 argptr = "\t\n\r\f\v ";
2579 argsize = 6;
2580 }
2581 else {
2582 if (_getbuffer(arg, &varg) < 0)
2583 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002584 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002585 argsize = varg.len;
2586 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002587 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002588 mysize = Py_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002589 right = rstrip_helper(myptr, mysize, argptr, argsize);
2590 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002591 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002592 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002593}
2594
2595PyDoc_STRVAR(decode_doc,
Victor Stinnerc911bbf2010-11-07 19:04:46 +00002596"B.decode(encoding='utf-8', errors='strict') -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002597\n\
Victor Stinnere14e2122010-11-07 18:41:46 +00002598Decode B using the codec registered for encoding. Default encoding\n\
2599is 'utf-8'. errors may be given to set a different error\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002600handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2601a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2602as well as any other name registered with codecs.register_error that is\n\
2603able to handle UnicodeDecodeErrors.");
2604
2605static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002606bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002607{
2608 const char *encoding = NULL;
2609 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002610 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002611
Benjamin Peterson308d6372009-09-18 21:42:35 +00002612 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002613 return NULL;
2614 if (encoding == NULL)
2615 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002616 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002617}
2618
2619PyDoc_STRVAR(alloc_doc,
2620"B.__alloc__() -> int\n\
2621\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002622Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002623
2624static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002625bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002626{
2627 return PyLong_FromSsize_t(self->ob_alloc);
2628}
2629
2630PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002631"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002632\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002633Concatenate any number of bytes/bytearray objects, with B\n\
2634in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002635
2636static PyObject *
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002637bytearray_join(PyObject *self, PyObject *iterable)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002638{
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002639 return stringlib_bytes_join(self, iterable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002640}
2641
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002642PyDoc_STRVAR(splitlines__doc__,
2643"B.splitlines([keepends]) -> list of lines\n\
2644\n\
2645Return a list of the lines in B, breaking at line boundaries.\n\
2646Line breaks are not included in the resulting list unless keepends\n\
2647is given and true.");
2648
2649static PyObject*
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002650bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002651{
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002652 static char *kwlist[] = {"keepends", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002653 int keepends = 0;
2654
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002655 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines",
2656 kwlist, &keepends))
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002657 return NULL;
2658
2659 return stringlib_splitlines(
2660 (PyObject*) self, PyByteArray_AS_STRING(self),
2661 PyByteArray_GET_SIZE(self), keepends
2662 );
2663}
2664
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002665PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002666"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002667\n\
2668Create a bytearray object from a string of hexadecimal numbers.\n\
2669Spaces between two numbers are accepted.\n\
2670Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2671
2672static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002673hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002674{
2675 if (c >= 128)
2676 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002677 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002678 return c - '0';
2679 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002680 if (Py_ISUPPER(c))
2681 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002682 if (c >= 'a' && c <= 'f')
2683 return c - 'a' + 10;
2684 }
2685 return -1;
2686}
2687
2688static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002689bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002690{
2691 PyObject *newbytes, *hexobj;
2692 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002693 Py_ssize_t hexlen, byteslen, i, j;
2694 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002695 void *data;
2696 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002697
2698 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2699 return NULL;
2700 assert(PyUnicode_Check(hexobj));
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002701 if (PyUnicode_READY(hexobj))
2702 return NULL;
2703 kind = PyUnicode_KIND(hexobj);
2704 data = PyUnicode_DATA(hexobj);
2705 hexlen = PyUnicode_GET_LENGTH(hexobj);
2706
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002707 byteslen = hexlen/2; /* This overestimates if there are spaces */
2708 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2709 if (!newbytes)
2710 return NULL;
2711 buf = PyByteArray_AS_STRING(newbytes);
2712 for (i = j = 0; i < hexlen; i += 2) {
2713 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002714 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002715 i++;
2716 if (i >= hexlen)
2717 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002718 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2719 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002720 if (top == -1 || bot == -1) {
2721 PyErr_Format(PyExc_ValueError,
2722 "non-hexadecimal number found in "
2723 "fromhex() arg at position %zd", i);
2724 goto error;
2725 }
2726 buf[j++] = (top << 4) + bot;
2727 }
2728 if (PyByteArray_Resize(newbytes, j) < 0)
2729 goto error;
2730 return newbytes;
2731
2732 error:
2733 Py_DECREF(newbytes);
2734 return NULL;
2735}
2736
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002737
2738static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002739_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002740{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002741 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002742 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002743 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002744
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002745 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002746 if (dict == NULL) {
2747 PyErr_Clear();
2748 dict = Py_None;
2749 Py_INCREF(dict);
2750 }
2751
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002752 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002753 if (proto < 3) {
2754 /* use str based reduction for backwards compatibility with Python 2.x */
2755 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002756 if (Py_SIZE(self))
2757 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002758 else
2759 latin1 = PyUnicode_FromString("");
2760 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2761 }
2762 else {
2763 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002764 if (Py_SIZE(self)) {
2765 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002766 }
2767 else {
2768 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2769 }
2770 }
2771}
2772
2773PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2774
2775static PyObject *
2776bytearray_reduce(PyByteArrayObject *self)
2777{
2778 return _common_reduce(self, 2);
2779}
2780
2781PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling.");
2782
2783static PyObject *
2784bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
2785{
2786 int proto = 0;
2787
2788 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
2789 return NULL;
2790
2791 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002792}
2793
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002794PyDoc_STRVAR(sizeof_doc,
2795"B.__sizeof__() -> int\n\
2796 \n\
2797Returns the size of B in memory, in bytes");
2798static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002799bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002800{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002801 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002802
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002803 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2804 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002805}
2806
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002807static PySequenceMethods bytearray_as_sequence = {
2808 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002809 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002810 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2811 (ssizeargfunc)bytearray_getitem, /* sq_item */
2812 0, /* sq_slice */
2813 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2814 0, /* sq_ass_slice */
2815 (objobjproc)bytearray_contains, /* sq_contains */
2816 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2817 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002818};
2819
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002820static PyMappingMethods bytearray_as_mapping = {
2821 (lenfunc)bytearray_length,
2822 (binaryfunc)bytearray_subscript,
2823 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002824};
2825
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002826static PyBufferProcs bytearray_as_buffer = {
2827 (getbufferproc)bytearray_getbuffer,
2828 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002829};
2830
2831static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002832bytearray_methods[] = {
2833 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2834 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002835 {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002836 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2837 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002838 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2839 _Py_capitalize__doc__},
2840 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00002841 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__},
2842 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002843 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002844 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002845 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Ezio Melotti745d54d2013-11-16 19:10:57 +02002846 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002847 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002848 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2849 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2850 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002851 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002852 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2853 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002854 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2855 _Py_isalnum__doc__},
2856 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2857 _Py_isalpha__doc__},
2858 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2859 _Py_isdigit__doc__},
2860 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2861 _Py_islower__doc__},
2862 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2863 _Py_isspace__doc__},
2864 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2865 _Py_istitle__doc__},
2866 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2867 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002868 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002869 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2870 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002871 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2872 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002873 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002874 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2875 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2876 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2877 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2878 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2879 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2880 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002881 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002882 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002883 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002884 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002885 {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__},
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002886 {"splitlines", (PyCFunction)bytearray_splitlines,
2887 METH_VARARGS | METH_KEYWORDS, splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002888 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002889 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002890 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002891 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2892 _Py_swapcase__doc__},
2893 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002894 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002895 translate__doc__},
2896 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2897 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2898 {NULL}
2899};
2900
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002901PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002902"bytearray(iterable_of_ints) -> bytearray\n\
2903bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002904bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2905bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2906bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002907\n\
2908Construct an mutable bytearray object from:\n\
2909 - an iterable yielding integers in range(256)\n\
2910 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002911 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002912 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002913 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002914
2915
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002916static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002917
2918PyTypeObject PyByteArray_Type = {
2919 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2920 "bytearray",
2921 sizeof(PyByteArrayObject),
2922 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002923 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002924 0, /* tp_print */
2925 0, /* tp_getattr */
2926 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002927 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002928 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002929 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002930 &bytearray_as_sequence, /* tp_as_sequence */
2931 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002932 0, /* tp_hash */
2933 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002934 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002935 PyObject_GenericGetAttr, /* tp_getattro */
2936 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002937 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002938 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002939 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002940 0, /* tp_traverse */
2941 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002942 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002943 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002944 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002945 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002946 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002947 0, /* tp_members */
2948 0, /* tp_getset */
2949 0, /* tp_base */
2950 0, /* tp_dict */
2951 0, /* tp_descr_get */
2952 0, /* tp_descr_set */
2953 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002954 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002955 PyType_GenericAlloc, /* tp_alloc */
2956 PyType_GenericNew, /* tp_new */
2957 PyObject_Del, /* tp_free */
2958};
2959
2960/*********************** Bytes Iterator ****************************/
2961
2962typedef struct {
2963 PyObject_HEAD
2964 Py_ssize_t it_index;
2965 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2966} bytesiterobject;
2967
2968static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002969bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002970{
2971 _PyObject_GC_UNTRACK(it);
2972 Py_XDECREF(it->it_seq);
2973 PyObject_GC_Del(it);
2974}
2975
2976static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002977bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002978{
2979 Py_VISIT(it->it_seq);
2980 return 0;
2981}
2982
2983static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002984bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002985{
2986 PyByteArrayObject *seq;
2987 PyObject *item;
2988
2989 assert(it != NULL);
2990 seq = it->it_seq;
2991 if (seq == NULL)
2992 return NULL;
2993 assert(PyByteArray_Check(seq));
2994
2995 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2996 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002997 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002998 if (item != NULL)
2999 ++it->it_index;
3000 return item;
3001 }
3002
3003 Py_DECREF(seq);
3004 it->it_seq = NULL;
3005 return NULL;
3006}
3007
3008static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003009bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003010{
3011 Py_ssize_t len = 0;
3012 if (it->it_seq)
3013 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3014 return PyLong_FromSsize_t(len);
3015}
3016
3017PyDoc_STRVAR(length_hint_doc,
3018 "Private method returning an estimate of len(list(it)).");
3019
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003020static PyObject *
3021bytearrayiter_reduce(bytesiterobject *it)
3022{
3023 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02003024 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003025 it->it_seq, it->it_index);
3026 } else {
3027 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
3028 if (u == NULL)
3029 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02003030 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003031 }
3032}
3033
3034static PyObject *
3035bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3036{
3037 Py_ssize_t index = PyLong_AsSsize_t(state);
3038 if (index == -1 && PyErr_Occurred())
3039 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +00003040 if (it->it_seq != NULL) {
3041 if (index < 0)
3042 index = 0;
3043 else if (index > PyByteArray_GET_SIZE(it->it_seq))
3044 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
3045 it->it_index = index;
3046 }
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003047 Py_RETURN_NONE;
3048}
3049
3050PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3051
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003052static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003053 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003054 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003055 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
3056 reduce_doc},
3057 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3058 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003059 {NULL, NULL} /* sentinel */
3060};
3061
3062PyTypeObject PyByteArrayIter_Type = {
3063 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3064 "bytearray_iterator", /* tp_name */
3065 sizeof(bytesiterobject), /* tp_basicsize */
3066 0, /* tp_itemsize */
3067 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003068 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003069 0, /* tp_print */
3070 0, /* tp_getattr */
3071 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003072 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003073 0, /* tp_repr */
3074 0, /* tp_as_number */
3075 0, /* tp_as_sequence */
3076 0, /* tp_as_mapping */
3077 0, /* tp_hash */
3078 0, /* tp_call */
3079 0, /* tp_str */
3080 PyObject_GenericGetAttr, /* tp_getattro */
3081 0, /* tp_setattro */
3082 0, /* tp_as_buffer */
3083 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3084 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003085 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003086 0, /* tp_clear */
3087 0, /* tp_richcompare */
3088 0, /* tp_weaklistoffset */
3089 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003090 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3091 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003092 0,
3093};
3094
3095static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003096bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003097{
3098 bytesiterobject *it;
3099
3100 if (!PyByteArray_Check(seq)) {
3101 PyErr_BadInternalCall();
3102 return NULL;
3103 }
3104 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3105 if (it == NULL)
3106 return NULL;
3107 it->it_index = 0;
3108 Py_INCREF(seq);
3109 it->it_seq = (PyByteArrayObject *)seq;
3110 _PyObject_GC_TRACK(it);
3111 return (PyObject *)it;
3112}