blob: c0f0819c122b0f0ae95b94d587a23f5ed5e3ddea [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;
456 assert(avail >= 0);
457
458 if (growth != 0) {
459 if (growth < 0) {
460 if (!_canresize(self))
461 return -1;
462 if (lo == 0) {
463 /* Shrink the buffer by advancing its logical start */
464 self->ob_start -= growth;
465 /*
466 0 lo hi old_size
467 | |<----avail----->|<-----tail------>|
468 | |<-bytes_len->|<-----tail------>|
469 0 new_lo new_hi new_size
470 */
471 }
472 else {
473 /*
474 0 lo hi old_size
475 | |<----avail----->|<-----tomove------>|
476 | |<-bytes_len->|<-----tomove------>|
477 0 lo new_hi new_size
478 */
479 memmove(buf + lo + bytes_len, buf + hi,
480 Py_SIZE(self) - hi);
481 }
482 }
483 /* XXX(nnorwitz): need to verify this can't overflow! */
484 if (PyByteArray_Resize(
485 (PyObject *)self, Py_SIZE(self) + growth) < 0)
486 return -1;
487 buf = PyByteArray_AS_STRING(self);
488 if (growth > 0) {
489 /* Make the place for the additional bytes */
490 /*
491 0 lo hi old_size
492 | |<-avail->|<-----tomove------>|
493 | |<---bytes_len-->|<-----tomove------>|
494 0 lo new_hi new_size
495 */
496 memmove(buf + lo + bytes_len, buf + hi,
497 Py_SIZE(self) - lo - bytes_len);
498 }
499 }
500
501 if (bytes_len > 0)
502 memcpy(buf + lo, bytes, bytes_len);
503 return 0;
504}
505
506static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000507bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000508 PyObject *values)
509{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200510 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000511 void *bytes;
512 Py_buffer vbytes;
513 int res = 0;
514
515 vbytes.len = -1;
516 if (values == (PyObject *)self) {
517 /* Make a copy and call this function recursively */
518 int err;
519 values = PyByteArray_FromObject(values);
520 if (values == NULL)
521 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000522 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000523 Py_DECREF(values);
524 return err;
525 }
526 if (values == NULL) {
527 /* del b[lo:hi] */
528 bytes = NULL;
529 needed = 0;
530 }
531 else {
532 if (_getbuffer(values, &vbytes) < 0) {
533 PyErr_Format(PyExc_TypeError,
Georg Brandl3dbca812008-07-23 16:10:53 +0000534 "can't set bytearray slice from %.100s",
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000535 Py_TYPE(values)->tp_name);
536 return -1;
537 }
538 needed = vbytes.len;
539 bytes = vbytes.buf;
540 }
541
542 if (lo < 0)
543 lo = 0;
544 if (hi < lo)
545 hi = lo;
546 if (hi > Py_SIZE(self))
547 hi = Py_SIZE(self);
548
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200549 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000550 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200551 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000552 return res;
553}
554
555static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000556bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000557{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000558 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000559
560 if (i < 0)
561 i += Py_SIZE(self);
562
563 if (i < 0 || i >= Py_SIZE(self)) {
564 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
565 return -1;
566 }
567
568 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000569 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000570
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000571 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000572 return -1;
573
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200574 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000575 return 0;
576}
577
578static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000579bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000580{
581 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200582 char *buf, *bytes;
583 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000584
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000585 if (PyIndex_Check(index)) {
586 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000587
588 if (i == -1 && PyErr_Occurred())
589 return -1;
590
591 if (i < 0)
592 i += PyByteArray_GET_SIZE(self);
593
594 if (i < 0 || i >= Py_SIZE(self)) {
595 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
596 return -1;
597 }
598
599 if (values == NULL) {
600 /* Fall through to slice assignment */
601 start = i;
602 stop = i + 1;
603 step = 1;
604 slicelen = 1;
605 }
606 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000607 int ival;
608 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000609 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200610 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000611 return 0;
612 }
613 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000614 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000615 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000616 PyByteArray_GET_SIZE(self),
617 &start, &stop, &step, &slicelen) < 0) {
618 return -1;
619 }
620 }
621 else {
622 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
623 return -1;
624 }
625
626 if (values == NULL) {
627 bytes = NULL;
628 needed = 0;
629 }
630 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100631 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200632 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
633 PyErr_SetString(PyExc_TypeError,
634 "can assign only bytes, buffers, or iterables "
635 "of ints in range(0, 256)");
636 return -1;
637 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000638 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000639 values = PyByteArray_FromObject(values);
640 if (values == NULL)
641 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000642 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000643 Py_DECREF(values);
644 return err;
645 }
646 else {
647 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200648 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000649 needed = Py_SIZE(values);
650 }
651 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
652 if ((step < 0 && start < stop) ||
653 (step > 0 && start > stop))
654 stop = start;
655 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200656 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000657 }
658 else {
659 if (needed == 0) {
660 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000661 size_t cur;
662 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000663
Antoine Pitrou5504e892008-12-06 21:27:53 +0000664 if (!_canresize(self))
665 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000666
667 if (slicelen == 0)
668 /* Nothing to do here. */
669 return 0;
670
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000671 if (step < 0) {
672 stop = start + 1;
673 start = stop + step * (slicelen - 1) - 1;
674 step = -step;
675 }
676 for (cur = start, i = 0;
677 i < slicelen; cur += step, i++) {
678 Py_ssize_t lim = step - 1;
679
Mark Dickinson66f575b2010-02-14 12:53:32 +0000680 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000681 lim = PyByteArray_GET_SIZE(self) - cur - 1;
682
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200683 memmove(buf + cur - i,
684 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000685 }
686 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000687 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000688 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200689 memmove(buf + cur - slicelen,
690 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000691 PyByteArray_GET_SIZE(self) - cur);
692 }
693 if (PyByteArray_Resize((PyObject *)self,
694 PyByteArray_GET_SIZE(self) - slicelen) < 0)
695 return -1;
696
697 return 0;
698 }
699 else {
700 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000701 Py_ssize_t i;
702 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000703
704 if (needed != slicelen) {
705 PyErr_Format(PyExc_ValueError,
706 "attempt to assign bytes of size %zd "
707 "to extended slice of size %zd",
708 needed, slicelen);
709 return -1;
710 }
711 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200712 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000713 return 0;
714 }
715 }
716}
717
718static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000719bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000720{
721 static char *kwlist[] = {"source", "encoding", "errors", 0};
722 PyObject *arg = NULL;
723 const char *encoding = NULL;
724 const char *errors = NULL;
725 Py_ssize_t count;
726 PyObject *it;
727 PyObject *(*iternext)(PyObject *);
728
729 if (Py_SIZE(self) != 0) {
730 /* Empty previous contents (yes, do this first of all!) */
731 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
732 return -1;
733 }
734
735 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000736 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000737 &arg, &encoding, &errors))
738 return -1;
739
740 /* Make a quick exit if no first argument */
741 if (arg == NULL) {
742 if (encoding != NULL || errors != NULL) {
743 PyErr_SetString(PyExc_TypeError,
744 "encoding or errors without sequence argument");
745 return -1;
746 }
747 return 0;
748 }
749
750 if (PyUnicode_Check(arg)) {
751 /* Encode via the codec registry */
752 PyObject *encoded, *new;
753 if (encoding == NULL) {
754 PyErr_SetString(PyExc_TypeError,
755 "string argument without an encoding");
756 return -1;
757 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000758 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000759 if (encoded == NULL)
760 return -1;
761 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000762 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000763 Py_DECREF(encoded);
764 if (new == NULL)
765 return -1;
766 Py_DECREF(new);
767 return 0;
768 }
769
770 /* If it's not unicode, there can't be encoding or errors */
771 if (encoding != NULL || errors != NULL) {
772 PyErr_SetString(PyExc_TypeError,
773 "encoding or errors without a string argument");
774 return -1;
775 }
776
777 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000778 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
779 if (count == -1 && PyErr_Occurred()) {
780 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000781 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000782 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000783 }
784 else if (count < 0) {
785 PyErr_SetString(PyExc_ValueError, "negative count");
786 return -1;
787 }
788 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000789 if (count > 0) {
790 if (PyByteArray_Resize((PyObject *)self, count))
791 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200792 memset(PyByteArray_AS_STRING(self), 0, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000793 }
794 return 0;
795 }
796
797 /* Use the buffer API */
798 if (PyObject_CheckBuffer(arg)) {
799 Py_ssize_t size;
800 Py_buffer view;
801 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
802 return -1;
803 size = view.len;
804 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200805 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
806 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200807 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000808 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000809 return 0;
810 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000811 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000812 return -1;
813 }
814
815 /* XXX Optimize this if the arguments is a list, tuple */
816
817 /* Get the iterator */
818 it = PyObject_GetIter(arg);
819 if (it == NULL)
820 return -1;
821 iternext = *Py_TYPE(it)->tp_iternext;
822
823 /* Run the iterator to exhaustion */
824 for (;;) {
825 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000826 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000827
828 /* Get the next item */
829 item = iternext(it);
830 if (item == NULL) {
831 if (PyErr_Occurred()) {
832 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
833 goto error;
834 PyErr_Clear();
835 }
836 break;
837 }
838
839 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000840 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000841 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000842 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000843 goto error;
844
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000845 /* Append the byte */
846 if (Py_SIZE(self) < self->ob_alloc)
847 Py_SIZE(self)++;
848 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
849 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200850 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000851 }
852
853 /* Clean up and return success */
854 Py_DECREF(it);
855 return 0;
856
857 error:
858 /* Error handling when it != NULL */
859 Py_DECREF(it);
860 return -1;
861}
862
863/* Mostly copied from string_repr, but without the
864 "smart quote" functionality. */
865static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000866bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000867{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000868 const char *quote_prefix = "bytearray(b";
869 const char *quote_postfix = ")";
870 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200871 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000872 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000873 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200874 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200875 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200876 char c;
877 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200878 int quote;
879 char *test, *start;
880 char *buffer;
881
882 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000883 PyErr_SetString(PyExc_OverflowError,
884 "bytearray object is too large to make repr");
885 return NULL;
886 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200887
888 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100889 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200890 if (buffer == NULL) {
891 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000892 return NULL;
893 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000894
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200895 /* Figure out which quote to use; single is preferred */
896 quote = '\'';
897 start = PyByteArray_AS_STRING(self);
898 for (test = start; test < start+length; ++test) {
899 if (*test == '"') {
900 quote = '\''; /* back to single */
901 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000902 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200903 else if (*test == '\'')
904 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000905 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200906
907 p = buffer;
908 while (*quote_prefix)
909 *p++ = *quote_prefix++;
910 *p++ = quote;
911
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200912 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200913 for (i = 0; i < length; i++) {
914 /* There's at least enough room for a hex escape
915 and a closing quote. */
916 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200917 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200918 if (c == '\'' || c == '\\')
919 *p++ = '\\', *p++ = c;
920 else if (c == '\t')
921 *p++ = '\\', *p++ = 't';
922 else if (c == '\n')
923 *p++ = '\\', *p++ = 'n';
924 else if (c == '\r')
925 *p++ = '\\', *p++ = 'r';
926 else if (c == 0)
927 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
928 else if (c < ' ' || c >= 0x7f) {
929 *p++ = '\\';
930 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200931 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
932 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200933 }
934 else
935 *p++ = c;
936 }
937 assert(newsize - (p - buffer) >= 1);
938 *p++ = quote;
939 while (*quote_postfix) {
940 *p++ = *quote_postfix++;
941 }
942
943 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100944 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200945 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000946}
947
948static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000949bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000950{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000951 if (Py_BytesWarningFlag) {
952 if (PyErr_WarnEx(PyExc_BytesWarning,
953 "str() on a bytearray instance", 1))
954 return NULL;
955 }
956 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000957}
958
959static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000960bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000961{
962 Py_ssize_t self_size, other_size;
963 Py_buffer self_bytes, other_bytes;
964 PyObject *res;
965 Py_ssize_t minsize;
966 int cmp;
967
968 /* Bytes can be compared to anything that supports the (binary)
969 buffer API. Except that a comparison with Unicode is always an
970 error, even if the comparison is for equality. */
971 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
972 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000973 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000974 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000975 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000976 return NULL;
977 }
978
Brian Curtindfc80e32011-08-10 20:28:54 -0500979 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000980 }
981
982 self_size = _getbuffer(self, &self_bytes);
983 if (self_size < 0) {
984 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -0500985 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000986 }
987
988 other_size = _getbuffer(other, &other_bytes);
989 if (other_size < 0) {
990 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +0000991 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -0500992 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000993 }
994
995 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
996 /* Shortcut: if the lengths differ, the objects differ */
997 cmp = (op == Py_NE);
998 }
999 else {
1000 minsize = self_size;
1001 if (other_size < minsize)
1002 minsize = other_size;
1003
1004 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1005 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1006
1007 if (cmp == 0) {
1008 if (self_size < other_size)
1009 cmp = -1;
1010 else if (self_size > other_size)
1011 cmp = 1;
1012 }
1013
1014 switch (op) {
1015 case Py_LT: cmp = cmp < 0; break;
1016 case Py_LE: cmp = cmp <= 0; break;
1017 case Py_EQ: cmp = cmp == 0; break;
1018 case Py_NE: cmp = cmp != 0; break;
1019 case Py_GT: cmp = cmp > 0; break;
1020 case Py_GE: cmp = cmp >= 0; break;
1021 }
1022 }
1023
1024 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001025 PyBuffer_Release(&self_bytes);
1026 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001027 Py_INCREF(res);
1028 return res;
1029}
1030
1031static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001032bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001033{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001034 if (self->ob_exports > 0) {
1035 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001036 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001037 PyErr_Print();
1038 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001039 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001040 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001041 }
1042 Py_TYPE(self)->tp_free((PyObject *)self);
1043}
1044
1045
1046/* -------------------------------------------------------------------- */
1047/* Methods */
1048
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001049#define FASTSEARCH fastsearch
1050#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001051#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001052#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001053#define STRINGLIB_LEN PyByteArray_GET_SIZE
1054#define STRINGLIB_STR PyByteArray_AS_STRING
1055#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001056#define STRINGLIB_ISSPACE Py_ISSPACE
1057#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001058#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1059#define STRINGLIB_MUTABLE 1
1060
1061#include "stringlib/fastsearch.h"
1062#include "stringlib/count.h"
1063#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001064#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001065#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001066#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001067#include "stringlib/ctype.h"
1068#include "stringlib/transmogrify.h"
1069
1070
1071/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1072were copied from the old char* style string object. */
1073
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001074/* helper macro to fixup start/end slice values */
1075#define ADJUST_INDICES(start, end, len) \
1076 if (end > len) \
1077 end = len; \
1078 else if (end < 0) { \
1079 end += len; \
1080 if (end < 0) \
1081 end = 0; \
1082 } \
1083 if (start < 0) { \
1084 start += len; \
1085 if (start < 0) \
1086 start = 0; \
1087 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001088
1089Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001090bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001091{
1092 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001093 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001094 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001095 const char *sub;
1096 Py_ssize_t sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001097 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1098 Py_ssize_t res;
1099
Antoine Pitrouac65d962011-10-20 23:54:17 +02001100 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1101 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001102 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001103
1104 if (subobj) {
1105 if (_getbuffer(subobj, &subbuf) < 0)
1106 return -2;
1107
1108 sub = subbuf.buf;
1109 sub_len = subbuf.len;
1110 }
1111 else {
1112 sub = &byte;
1113 sub_len = 1;
1114 }
1115
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001116 if (dir > 0)
1117 res = stringlib_find_slice(
1118 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001119 sub, sub_len, start, end);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001120 else
1121 res = stringlib_rfind_slice(
1122 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001123 sub, sub_len, start, end);
1124
1125 if (subobj)
1126 PyBuffer_Release(&subbuf);
1127
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001128 return res;
1129}
1130
1131PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001132"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001133\n\
1134Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001135such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001136arguments start and end are interpreted as in slice notation.\n\
1137\n\
1138Return -1 on failure.");
1139
1140static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001141bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001142{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001143 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001144 if (result == -2)
1145 return NULL;
1146 return PyLong_FromSsize_t(result);
1147}
1148
1149PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001150"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001151\n\
1152Return the number of non-overlapping occurrences of subsection sub in\n\
1153bytes B[start:end]. Optional arguments start and end are interpreted\n\
1154as in slice notation.");
1155
1156static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001157bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001158{
1159 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001160 const char *str = PyByteArray_AS_STRING(self), *sub;
1161 Py_ssize_t sub_len;
1162 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001163 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001164
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001165 Py_buffer vsub;
1166 PyObject *count_obj;
1167
Antoine Pitrouac65d962011-10-20 23:54:17 +02001168 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1169 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001170 return NULL;
1171
Antoine Pitrouac65d962011-10-20 23:54:17 +02001172 if (sub_obj) {
1173 if (_getbuffer(sub_obj, &vsub) < 0)
1174 return NULL;
1175
1176 sub = vsub.buf;
1177 sub_len = vsub.len;
1178 }
1179 else {
1180 sub = &byte;
1181 sub_len = 1;
1182 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001183
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001184 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001185
1186 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001187 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001188 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001189
1190 if (sub_obj)
1191 PyBuffer_Release(&vsub);
1192
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001193 return count_obj;
1194}
1195
Eli Bendersky4db28d32011-03-03 18:21:02 +00001196PyDoc_STRVAR(clear__doc__,
1197"B.clear() -> None\n\
1198\n\
1199Remove all items from B.");
1200
Victor Stinner6430fd52011-09-29 04:02:13 +02001201static PyObject *
Eli Bendersky4db28d32011-03-03 18:21:02 +00001202bytearray_clear(PyByteArrayObject *self)
1203{
1204 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1205 return NULL;
1206 Py_RETURN_NONE;
1207}
1208
1209PyDoc_STRVAR(copy__doc__,
1210"B.copy() -> bytearray\n\
1211\n\
1212Return a copy of B.");
1213
1214static PyObject *
1215bytearray_copy(PyByteArrayObject *self)
1216{
1217 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1218 PyByteArray_GET_SIZE(self));
1219}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001220
1221PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001222"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001223\n\
1224Like B.find() but raise ValueError when the subsection is not found.");
1225
1226static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001227bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001228{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001229 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001230 if (result == -2)
1231 return NULL;
1232 if (result == -1) {
1233 PyErr_SetString(PyExc_ValueError,
1234 "subsection not found");
1235 return NULL;
1236 }
1237 return PyLong_FromSsize_t(result);
1238}
1239
1240
1241PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001242"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001243\n\
1244Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001245such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001246arguments start and end are interpreted as in slice notation.\n\
1247\n\
1248Return -1 on failure.");
1249
1250static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001251bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001252{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001253 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001254 if (result == -2)
1255 return NULL;
1256 return PyLong_FromSsize_t(result);
1257}
1258
1259
1260PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001261"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001262\n\
1263Like B.rfind() but raise ValueError when the subsection is not found.");
1264
1265static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001266bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001267{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001268 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001269 if (result == -2)
1270 return NULL;
1271 if (result == -1) {
1272 PyErr_SetString(PyExc_ValueError,
1273 "subsection not found");
1274 return NULL;
1275 }
1276 return PyLong_FromSsize_t(result);
1277}
1278
1279
1280static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001281bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001282{
1283 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1284 if (ival == -1 && PyErr_Occurred()) {
1285 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001286 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001287 PyErr_Clear();
1288 if (_getbuffer(arg, &varg) < 0)
1289 return -1;
1290 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1291 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001292 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001293 return pos >= 0;
1294 }
1295 if (ival < 0 || ival >= 256) {
1296 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1297 return -1;
1298 }
1299
Antoine Pitrou0010d372010-08-15 17:12:55 +00001300 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001301}
1302
1303
1304/* Matches the end (direction >= 0) or start (direction < 0) of self
1305 * against substr, using the start and end arguments. Returns
1306 * -1 on error, 0 if not found and 1 if found.
1307 */
1308Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001309_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001310 Py_ssize_t end, int direction)
1311{
1312 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1313 const char* str;
1314 Py_buffer vsubstr;
1315 int rv = 0;
1316
1317 str = PyByteArray_AS_STRING(self);
1318
1319 if (_getbuffer(substr, &vsubstr) < 0)
1320 return -1;
1321
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001322 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001323
1324 if (direction < 0) {
1325 /* startswith */
1326 if (start+vsubstr.len > len) {
1327 goto done;
1328 }
1329 } else {
1330 /* endswith */
1331 if (end-start < vsubstr.len || start > len) {
1332 goto done;
1333 }
1334
1335 if (end-vsubstr.len > start)
1336 start = end - vsubstr.len;
1337 }
1338 if (end-start >= vsubstr.len)
1339 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1340
1341done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001342 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001343 return rv;
1344}
1345
1346
1347PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001348"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001349\n\
1350Return True if B starts with the specified prefix, False otherwise.\n\
1351With optional start, test B beginning at that position.\n\
1352With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001353prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001354
1355static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001356bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001357{
1358 Py_ssize_t start = 0;
1359 Py_ssize_t end = PY_SSIZE_T_MAX;
1360 PyObject *subobj;
1361 int result;
1362
Jesus Ceaac451502011-04-20 17:09:23 +02001363 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001364 return NULL;
1365 if (PyTuple_Check(subobj)) {
1366 Py_ssize_t i;
1367 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001368 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001369 PyTuple_GET_ITEM(subobj, i),
1370 start, end, -1);
1371 if (result == -1)
1372 return NULL;
1373 else if (result) {
1374 Py_RETURN_TRUE;
1375 }
1376 }
1377 Py_RETURN_FALSE;
1378 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001379 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001380 if (result == -1) {
1381 if (PyErr_ExceptionMatches(PyExc_TypeError))
1382 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1383 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001384 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001385 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001386 else
1387 return PyBool_FromLong(result);
1388}
1389
1390PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001391"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001392\n\
1393Return True if B ends with the specified suffix, False otherwise.\n\
1394With optional start, test B beginning at that position.\n\
1395With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001396suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001397
1398static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001399bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001400{
1401 Py_ssize_t start = 0;
1402 Py_ssize_t end = PY_SSIZE_T_MAX;
1403 PyObject *subobj;
1404 int result;
1405
Jesus Ceaac451502011-04-20 17:09:23 +02001406 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001407 return NULL;
1408 if (PyTuple_Check(subobj)) {
1409 Py_ssize_t i;
1410 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001411 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001412 PyTuple_GET_ITEM(subobj, i),
1413 start, end, +1);
1414 if (result == -1)
1415 return NULL;
1416 else if (result) {
1417 Py_RETURN_TRUE;
1418 }
1419 }
1420 Py_RETURN_FALSE;
1421 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001422 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001423 if (result == -1) {
1424 if (PyErr_ExceptionMatches(PyExc_TypeError))
1425 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1426 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001427 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001428 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001429 else
1430 return PyBool_FromLong(result);
1431}
1432
1433
1434PyDoc_STRVAR(translate__doc__,
1435"B.translate(table[, deletechars]) -> bytearray\n\
1436\n\
1437Return a copy of B, where all characters occurring in the\n\
1438optional argument deletechars are removed, and the remaining\n\
1439characters have been mapped through the given translation\n\
1440table, which must be a bytes object of length 256.");
1441
1442static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001443bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001444{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001445 char *input, *output;
1446 const char *table;
1447 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001448 PyObject *input_obj = (PyObject*)self;
1449 const char *output_start;
1450 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001451 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001452 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001453 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001454 Py_buffer vtable, vdel;
1455
1456 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1457 &tableobj, &delobj))
1458 return NULL;
1459
Georg Brandlccc47b62008-12-28 11:44:14 +00001460 if (tableobj == Py_None) {
1461 table = NULL;
1462 tableobj = NULL;
1463 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001464 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001465 } else {
1466 if (vtable.len != 256) {
1467 PyErr_SetString(PyExc_ValueError,
1468 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001469 PyBuffer_Release(&vtable);
1470 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001471 }
1472 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001473 }
1474
1475 if (delobj != NULL) {
1476 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001477 if (tableobj != NULL)
1478 PyBuffer_Release(&vtable);
1479 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001480 }
1481 }
1482 else {
1483 vdel.buf = NULL;
1484 vdel.len = 0;
1485 }
1486
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001487 inlen = PyByteArray_GET_SIZE(input_obj);
1488 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1489 if (result == NULL)
1490 goto done;
1491 output_start = output = PyByteArray_AsString(result);
1492 input = PyByteArray_AS_STRING(input_obj);
1493
Georg Brandlccc47b62008-12-28 11:44:14 +00001494 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001495 /* If no deletions are required, use faster code */
1496 for (i = inlen; --i >= 0; ) {
1497 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001498 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001499 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001500 goto done;
1501 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001502
1503 if (table == NULL) {
1504 for (i = 0; i < 256; i++)
1505 trans_table[i] = Py_CHARMASK(i);
1506 } else {
1507 for (i = 0; i < 256; i++)
1508 trans_table[i] = Py_CHARMASK(table[i]);
1509 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001510
1511 for (i = 0; i < vdel.len; i++)
1512 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1513
1514 for (i = inlen; --i >= 0; ) {
1515 c = Py_CHARMASK(*input++);
1516 if (trans_table[c] != -1)
1517 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1518 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001519 }
1520 /* Fix the size of the resulting string */
1521 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001522 if (PyByteArray_Resize(result, output - output_start) < 0) {
1523 Py_CLEAR(result);
1524 goto done;
1525 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001526
1527done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001528 if (tableobj != NULL)
1529 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001530 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001531 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001532 return result;
1533}
1534
1535
Georg Brandlabc38772009-04-12 15:51:51 +00001536static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001537bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001538{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001539 return _Py_bytes_maketrans(args);
Georg Brandlabc38772009-04-12 15:51:51 +00001540}
1541
1542
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001543/* find and count characters and substrings */
1544
1545#define findchar(target, target_len, c) \
1546 ((char *)memchr((const void *)(target), c, target_len))
1547
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001548
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001549/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001550Py_LOCAL(PyByteArrayObject *)
1551return_self(PyByteArrayObject *self)
1552{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001553 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001554 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1555 PyByteArray_AS_STRING(self),
1556 PyByteArray_GET_SIZE(self));
1557}
1558
1559Py_LOCAL_INLINE(Py_ssize_t)
1560countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1561{
1562 Py_ssize_t count=0;
1563 const char *start=target;
1564 const char *end=target+target_len;
1565
1566 while ( (start=findchar(start, end-start, c)) != NULL ) {
1567 count++;
1568 if (count >= maxcount)
1569 break;
1570 start += 1;
1571 }
1572 return count;
1573}
1574
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001575
1576/* Algorithms for different cases of string replacement */
1577
1578/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1579Py_LOCAL(PyByteArrayObject *)
1580replace_interleave(PyByteArrayObject *self,
1581 const char *to_s, Py_ssize_t to_len,
1582 Py_ssize_t maxcount)
1583{
1584 char *self_s, *result_s;
1585 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001586 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001587 PyByteArrayObject *result;
1588
1589 self_len = PyByteArray_GET_SIZE(self);
1590
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001591 /* 1 at the end plus 1 after every character;
1592 count = min(maxcount, self_len + 1) */
1593 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001594 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001595 else
1596 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1597 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001598
1599 /* Check for overflow */
1600 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001601 assert(count > 0);
1602 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001603 PyErr_SetString(PyExc_OverflowError,
1604 "replace string is too long");
1605 return NULL;
1606 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001607 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001608
1609 if (! (result = (PyByteArrayObject *)
1610 PyByteArray_FromStringAndSize(NULL, result_len)) )
1611 return NULL;
1612
1613 self_s = PyByteArray_AS_STRING(self);
1614 result_s = PyByteArray_AS_STRING(result);
1615
1616 /* TODO: special case single character, which doesn't need memcpy */
1617
1618 /* Lay the first one down (guaranteed this will occur) */
1619 Py_MEMCPY(result_s, to_s, to_len);
1620 result_s += to_len;
1621 count -= 1;
1622
1623 for (i=0; i<count; i++) {
1624 *result_s++ = *self_s++;
1625 Py_MEMCPY(result_s, to_s, to_len);
1626 result_s += to_len;
1627 }
1628
1629 /* Copy the rest of the original string */
1630 Py_MEMCPY(result_s, self_s, self_len-i);
1631
1632 return result;
1633}
1634
1635/* Special case for deleting a single character */
1636/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1637Py_LOCAL(PyByteArrayObject *)
1638replace_delete_single_character(PyByteArrayObject *self,
1639 char from_c, Py_ssize_t maxcount)
1640{
1641 char *self_s, *result_s;
1642 char *start, *next, *end;
1643 Py_ssize_t self_len, result_len;
1644 Py_ssize_t count;
1645 PyByteArrayObject *result;
1646
1647 self_len = PyByteArray_GET_SIZE(self);
1648 self_s = PyByteArray_AS_STRING(self);
1649
1650 count = countchar(self_s, self_len, from_c, maxcount);
1651 if (count == 0) {
1652 return return_self(self);
1653 }
1654
1655 result_len = self_len - count; /* from_len == 1 */
1656 assert(result_len>=0);
1657
1658 if ( (result = (PyByteArrayObject *)
1659 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1660 return NULL;
1661 result_s = PyByteArray_AS_STRING(result);
1662
1663 start = self_s;
1664 end = self_s + self_len;
1665 while (count-- > 0) {
1666 next = findchar(start, end-start, from_c);
1667 if (next == NULL)
1668 break;
1669 Py_MEMCPY(result_s, start, next-start);
1670 result_s += (next-start);
1671 start = next+1;
1672 }
1673 Py_MEMCPY(result_s, start, end-start);
1674
1675 return result;
1676}
1677
1678/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1679
1680Py_LOCAL(PyByteArrayObject *)
1681replace_delete_substring(PyByteArrayObject *self,
1682 const char *from_s, Py_ssize_t from_len,
1683 Py_ssize_t maxcount)
1684{
1685 char *self_s, *result_s;
1686 char *start, *next, *end;
1687 Py_ssize_t self_len, result_len;
1688 Py_ssize_t count, offset;
1689 PyByteArrayObject *result;
1690
1691 self_len = PyByteArray_GET_SIZE(self);
1692 self_s = PyByteArray_AS_STRING(self);
1693
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001694 count = stringlib_count(self_s, self_len,
1695 from_s, from_len,
1696 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001697
1698 if (count == 0) {
1699 /* no matches */
1700 return return_self(self);
1701 }
1702
1703 result_len = self_len - (count * from_len);
1704 assert (result_len>=0);
1705
1706 if ( (result = (PyByteArrayObject *)
1707 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1708 return NULL;
1709
1710 result_s = PyByteArray_AS_STRING(result);
1711
1712 start = self_s;
1713 end = self_s + self_len;
1714 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001715 offset = stringlib_find(start, end-start,
1716 from_s, from_len,
1717 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001718 if (offset == -1)
1719 break;
1720 next = start + offset;
1721
1722 Py_MEMCPY(result_s, start, next-start);
1723
1724 result_s += (next-start);
1725 start = next+from_len;
1726 }
1727 Py_MEMCPY(result_s, start, end-start);
1728 return result;
1729}
1730
1731/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1732Py_LOCAL(PyByteArrayObject *)
1733replace_single_character_in_place(PyByteArrayObject *self,
1734 char from_c, char to_c,
1735 Py_ssize_t maxcount)
1736{
Antoine Pitroud1188562010-06-09 16:38:55 +00001737 char *self_s, *result_s, *start, *end, *next;
1738 Py_ssize_t self_len;
1739 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001740
Antoine Pitroud1188562010-06-09 16:38:55 +00001741 /* The result string will be the same size */
1742 self_s = PyByteArray_AS_STRING(self);
1743 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001744
Antoine Pitroud1188562010-06-09 16:38:55 +00001745 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001746
Antoine Pitroud1188562010-06-09 16:38:55 +00001747 if (next == NULL) {
1748 /* No matches; return the original bytes */
1749 return return_self(self);
1750 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001751
Antoine Pitroud1188562010-06-09 16:38:55 +00001752 /* Need to make a new bytes */
1753 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1754 if (result == NULL)
1755 return NULL;
1756 result_s = PyByteArray_AS_STRING(result);
1757 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001758
Antoine Pitroud1188562010-06-09 16:38:55 +00001759 /* change everything in-place, starting with this one */
1760 start = result_s + (next-self_s);
1761 *start = to_c;
1762 start++;
1763 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001764
Antoine Pitroud1188562010-06-09 16:38:55 +00001765 while (--maxcount > 0) {
1766 next = findchar(start, end-start, from_c);
1767 if (next == NULL)
1768 break;
1769 *next = to_c;
1770 start = next+1;
1771 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001772
Antoine Pitroud1188562010-06-09 16:38:55 +00001773 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001774}
1775
1776/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1777Py_LOCAL(PyByteArrayObject *)
1778replace_substring_in_place(PyByteArrayObject *self,
1779 const char *from_s, Py_ssize_t from_len,
1780 const char *to_s, Py_ssize_t to_len,
1781 Py_ssize_t maxcount)
1782{
1783 char *result_s, *start, *end;
1784 char *self_s;
1785 Py_ssize_t self_len, offset;
1786 PyByteArrayObject *result;
1787
1788 /* The result bytes will be the same size */
1789
1790 self_s = PyByteArray_AS_STRING(self);
1791 self_len = PyByteArray_GET_SIZE(self);
1792
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001793 offset = stringlib_find(self_s, self_len,
1794 from_s, from_len,
1795 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001796 if (offset == -1) {
1797 /* No matches; return the original bytes */
1798 return return_self(self);
1799 }
1800
1801 /* Need to make a new bytes */
1802 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1803 if (result == NULL)
1804 return NULL;
1805 result_s = PyByteArray_AS_STRING(result);
1806 Py_MEMCPY(result_s, self_s, self_len);
1807
1808 /* change everything in-place, starting with this one */
1809 start = result_s + offset;
1810 Py_MEMCPY(start, to_s, from_len);
1811 start += from_len;
1812 end = result_s + self_len;
1813
1814 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001815 offset = stringlib_find(start, end-start,
1816 from_s, from_len,
1817 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001818 if (offset==-1)
1819 break;
1820 Py_MEMCPY(start+offset, to_s, from_len);
1821 start += offset+from_len;
1822 }
1823
1824 return result;
1825}
1826
1827/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1828Py_LOCAL(PyByteArrayObject *)
1829replace_single_character(PyByteArrayObject *self,
1830 char from_c,
1831 const char *to_s, Py_ssize_t to_len,
1832 Py_ssize_t maxcount)
1833{
1834 char *self_s, *result_s;
1835 char *start, *next, *end;
1836 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001837 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001838 PyByteArrayObject *result;
1839
1840 self_s = PyByteArray_AS_STRING(self);
1841 self_len = PyByteArray_GET_SIZE(self);
1842
1843 count = countchar(self_s, self_len, from_c, maxcount);
1844 if (count == 0) {
1845 /* no matches, return unchanged */
1846 return return_self(self);
1847 }
1848
1849 /* use the difference between current and new, hence the "-1" */
1850 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001851 assert(count > 0);
1852 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001853 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1854 return NULL;
1855 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001856 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001857
1858 if ( (result = (PyByteArrayObject *)
1859 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1860 return NULL;
1861 result_s = PyByteArray_AS_STRING(result);
1862
1863 start = self_s;
1864 end = self_s + self_len;
1865 while (count-- > 0) {
1866 next = findchar(start, end-start, from_c);
1867 if (next == NULL)
1868 break;
1869
1870 if (next == start) {
1871 /* replace with the 'to' */
1872 Py_MEMCPY(result_s, to_s, to_len);
1873 result_s += to_len;
1874 start += 1;
1875 } else {
1876 /* copy the unchanged old then the 'to' */
1877 Py_MEMCPY(result_s, start, next-start);
1878 result_s += (next-start);
1879 Py_MEMCPY(result_s, to_s, to_len);
1880 result_s += to_len;
1881 start = next+1;
1882 }
1883 }
1884 /* Copy the remainder of the remaining bytes */
1885 Py_MEMCPY(result_s, start, end-start);
1886
1887 return result;
1888}
1889
1890/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1891Py_LOCAL(PyByteArrayObject *)
1892replace_substring(PyByteArrayObject *self,
1893 const char *from_s, Py_ssize_t from_len,
1894 const char *to_s, Py_ssize_t to_len,
1895 Py_ssize_t maxcount)
1896{
1897 char *self_s, *result_s;
1898 char *start, *next, *end;
1899 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001900 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001901 PyByteArrayObject *result;
1902
1903 self_s = PyByteArray_AS_STRING(self);
1904 self_len = PyByteArray_GET_SIZE(self);
1905
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001906 count = stringlib_count(self_s, self_len,
1907 from_s, from_len,
1908 maxcount);
1909
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001910 if (count == 0) {
1911 /* no matches, return unchanged */
1912 return return_self(self);
1913 }
1914
1915 /* Check for overflow */
1916 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001917 assert(count > 0);
1918 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001919 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1920 return NULL;
1921 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001922 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001923
1924 if ( (result = (PyByteArrayObject *)
1925 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1926 return NULL;
1927 result_s = PyByteArray_AS_STRING(result);
1928
1929 start = self_s;
1930 end = self_s + self_len;
1931 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001932 offset = stringlib_find(start, end-start,
1933 from_s, from_len,
1934 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001935 if (offset == -1)
1936 break;
1937 next = start+offset;
1938 if (next == start) {
1939 /* replace with the 'to' */
1940 Py_MEMCPY(result_s, to_s, to_len);
1941 result_s += to_len;
1942 start += from_len;
1943 } else {
1944 /* copy the unchanged old then the 'to' */
1945 Py_MEMCPY(result_s, start, next-start);
1946 result_s += (next-start);
1947 Py_MEMCPY(result_s, to_s, to_len);
1948 result_s += to_len;
1949 start = next+from_len;
1950 }
1951 }
1952 /* Copy the remainder of the remaining bytes */
1953 Py_MEMCPY(result_s, start, end-start);
1954
1955 return result;
1956}
1957
1958
1959Py_LOCAL(PyByteArrayObject *)
1960replace(PyByteArrayObject *self,
1961 const char *from_s, Py_ssize_t from_len,
1962 const char *to_s, Py_ssize_t to_len,
1963 Py_ssize_t maxcount)
1964{
1965 if (maxcount < 0) {
1966 maxcount = PY_SSIZE_T_MAX;
1967 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1968 /* nothing to do; return the original bytes */
1969 return return_self(self);
1970 }
1971
1972 if (maxcount == 0 ||
1973 (from_len == 0 && to_len == 0)) {
1974 /* nothing to do; return the original bytes */
1975 return return_self(self);
1976 }
1977
1978 /* Handle zero-length special cases */
1979
1980 if (from_len == 0) {
1981 /* insert the 'to' bytes everywhere. */
1982 /* >>> "Python".replace("", ".") */
1983 /* '.P.y.t.h.o.n.' */
1984 return replace_interleave(self, to_s, to_len, maxcount);
1985 }
1986
1987 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1988 /* point for an empty self bytes to generate a non-empty bytes */
1989 /* Special case so the remaining code always gets a non-empty bytes */
1990 if (PyByteArray_GET_SIZE(self) == 0) {
1991 return return_self(self);
1992 }
1993
1994 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00001995 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001996 if (from_len == 1) {
1997 return replace_delete_single_character(
1998 self, from_s[0], maxcount);
1999 } else {
2000 return replace_delete_substring(self, from_s, from_len, maxcount);
2001 }
2002 }
2003
2004 /* Handle special case where both bytes have the same length */
2005
2006 if (from_len == to_len) {
2007 if (from_len == 1) {
2008 return replace_single_character_in_place(
2009 self,
2010 from_s[0],
2011 to_s[0],
2012 maxcount);
2013 } else {
2014 return replace_substring_in_place(
2015 self, from_s, from_len, to_s, to_len, maxcount);
2016 }
2017 }
2018
2019 /* Otherwise use the more generic algorithms */
2020 if (from_len == 1) {
2021 return replace_single_character(self, from_s[0],
2022 to_s, to_len, maxcount);
2023 } else {
2024 /* len('from')>=2, len('to')>=1 */
2025 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2026 }
2027}
2028
2029
2030PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002031"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002032\n\
2033Return a copy of B with all occurrences of subsection\n\
2034old replaced by new. If the optional argument count is\n\
2035given, only the first count occurrences are replaced.");
2036
2037static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002038bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002039{
2040 Py_ssize_t count = -1;
2041 PyObject *from, *to, *res;
2042 Py_buffer vfrom, vto;
2043
2044 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2045 return NULL;
2046
2047 if (_getbuffer(from, &vfrom) < 0)
2048 return NULL;
2049 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +00002050 PyBuffer_Release(&vfrom);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002051 return NULL;
2052 }
2053
2054 res = (PyObject *)replace((PyByteArrayObject *) self,
2055 vfrom.buf, vfrom.len,
2056 vto.buf, vto.len, count);
2057
Martin v. Löwis423be952008-08-13 15:53:07 +00002058 PyBuffer_Release(&vfrom);
2059 PyBuffer_Release(&vto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002060 return res;
2061}
2062
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002063PyDoc_STRVAR(split__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002064"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002065\n\
2066Return a list of the sections in B, using sep as the delimiter.\n\
2067If sep is not given, B is split on ASCII whitespace characters\n\
2068(space, tab, return, newline, formfeed, vertical tab).\n\
2069If maxsplit is given, at most maxsplit splits are done.");
2070
2071static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002072bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002073{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002074 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002075 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2076 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002077 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002078 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002079 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002080
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002081 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
2082 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002083 return NULL;
2084 if (maxsplit < 0)
2085 maxsplit = PY_SSIZE_T_MAX;
2086
2087 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002088 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002089
2090 if (_getbuffer(subobj, &vsub) < 0)
2091 return NULL;
2092 sub = vsub.buf;
2093 n = vsub.len;
2094
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002095 list = stringlib_split(
2096 (PyObject*) self, s, len, sub, n, maxsplit
2097 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002098 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002099 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002100}
2101
2102PyDoc_STRVAR(partition__doc__,
2103"B.partition(sep) -> (head, sep, tail)\n\
2104\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002105Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002106the separator itself, and the part after it. If the separator is not\n\
2107found, returns B and two empty bytearray objects.");
2108
2109static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002110bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002111{
2112 PyObject *bytesep, *result;
2113
2114 bytesep = PyByteArray_FromObject(sep_obj);
2115 if (! bytesep)
2116 return NULL;
2117
2118 result = stringlib_partition(
2119 (PyObject*) self,
2120 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2121 bytesep,
2122 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2123 );
2124
2125 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002126 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002127}
2128
2129PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002130"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002131\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002132Search for the separator sep in B, starting at the end of B,\n\
2133and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002134part after it. If the separator is not found, returns two empty\n\
2135bytearray objects and B.");
2136
2137static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002138bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002139{
2140 PyObject *bytesep, *result;
2141
2142 bytesep = PyByteArray_FromObject(sep_obj);
2143 if (! bytesep)
2144 return NULL;
2145
2146 result = stringlib_rpartition(
2147 (PyObject*) self,
2148 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2149 bytesep,
2150 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2151 );
2152
2153 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002154 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002155}
2156
2157PyDoc_STRVAR(rsplit__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002158"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002159\n\
2160Return a list of the sections in B, using sep as the delimiter,\n\
2161starting at the end of B and working to the front.\n\
2162If sep is not given, B is split on ASCII whitespace characters\n\
2163(space, tab, return, newline, formfeed, vertical tab).\n\
2164If maxsplit is given, at most maxsplit splits are done.");
2165
2166static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002167bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002168{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002169 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002170 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2171 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002172 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002173 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002174 Py_buffer vsub;
2175
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002176 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit",
2177 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002178 return NULL;
2179 if (maxsplit < 0)
2180 maxsplit = PY_SSIZE_T_MAX;
2181
2182 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002183 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002184
2185 if (_getbuffer(subobj, &vsub) < 0)
2186 return NULL;
2187 sub = vsub.buf;
2188 n = vsub.len;
2189
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002190 list = stringlib_rsplit(
2191 (PyObject*) self, s, len, sub, n, maxsplit
2192 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002193 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002194 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002195}
2196
2197PyDoc_STRVAR(reverse__doc__,
2198"B.reverse() -> None\n\
2199\n\
2200Reverse the order of the values in B in place.");
2201static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002202bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002203{
2204 char swap, *head, *tail;
2205 Py_ssize_t i, j, n = Py_SIZE(self);
2206
2207 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002208 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002209 tail = head + n - 1;
2210 for (i = 0; i < j; i++) {
2211 swap = *head;
2212 *head++ = *tail;
2213 *tail-- = swap;
2214 }
2215
2216 Py_RETURN_NONE;
2217}
2218
2219PyDoc_STRVAR(insert__doc__,
2220"B.insert(index, int) -> None\n\
2221\n\
2222Insert a single item into the bytearray before the given index.");
2223static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002224bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002225{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002226 PyObject *value;
2227 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002228 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002229 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002230
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002231 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002232 return NULL;
2233
2234 if (n == PY_SSIZE_T_MAX) {
2235 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002236 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002237 return NULL;
2238 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002239 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002240 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002241 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2242 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002243 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002244
2245 if (where < 0) {
2246 where += n;
2247 if (where < 0)
2248 where = 0;
2249 }
2250 if (where > n)
2251 where = n;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002252 memmove(buf + where + 1, buf + where, n - where);
2253 buf[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002254
2255 Py_RETURN_NONE;
2256}
2257
2258PyDoc_STRVAR(append__doc__,
2259"B.append(int) -> None\n\
2260\n\
2261Append a single item to the end of B.");
2262static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002263bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002264{
2265 int value;
2266 Py_ssize_t n = Py_SIZE(self);
2267
2268 if (! _getbytevalue(arg, &value))
2269 return NULL;
2270 if (n == PY_SSIZE_T_MAX) {
2271 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002272 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002273 return NULL;
2274 }
2275 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2276 return NULL;
2277
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002278 PyByteArray_AS_STRING(self)[n] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002279
2280 Py_RETURN_NONE;
2281}
2282
2283PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002284"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002285\n\
2286Append all the elements from the iterator or sequence to the\n\
2287end of B.");
2288static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002289bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002290{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002291 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002292 Py_ssize_t buf_size = 0, len = 0;
2293 int value;
2294 char *buf;
2295
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002296 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002297 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002298 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002299 return NULL;
2300
2301 Py_RETURN_NONE;
2302 }
2303
2304 it = PyObject_GetIter(arg);
2305 if (it == NULL)
2306 return NULL;
2307
Ezio Melotti42da6632011-03-15 05:18:48 +02002308 /* Try to determine the length of the argument. 32 is arbitrary. */
Armin Ronacheraa9a79d2012-10-06 14:03:24 +02002309 buf_size = PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002310 if (buf_size == -1) {
2311 Py_DECREF(it);
2312 return NULL;
2313 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002314
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002315 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002316 if (bytearray_obj == NULL) {
2317 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002318 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002319 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002320 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002321
2322 while ((item = PyIter_Next(it)) != NULL) {
2323 if (! _getbytevalue(item, &value)) {
2324 Py_DECREF(item);
2325 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002326 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002327 return NULL;
2328 }
2329 buf[len++] = value;
2330 Py_DECREF(item);
2331
2332 if (len >= buf_size) {
2333 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002334 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002335 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002336 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002337 return NULL;
2338 }
2339 /* Recompute the `buf' pointer, since the resizing operation may
2340 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002341 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002342 }
2343 }
2344 Py_DECREF(it);
2345
2346 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002347 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2348 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002349 return NULL;
2350 }
2351
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002352 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2353 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002354 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002355 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002356 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002357
2358 Py_RETURN_NONE;
2359}
2360
2361PyDoc_STRVAR(pop__doc__,
2362"B.pop([index]) -> int\n\
2363\n\
2364Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002365argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002366static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002367bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002368{
2369 int value;
2370 Py_ssize_t where = -1, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002371 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002372
2373 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2374 return NULL;
2375
2376 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002377 PyErr_SetString(PyExc_IndexError,
2378 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002379 return NULL;
2380 }
2381 if (where < 0)
2382 where += Py_SIZE(self);
2383 if (where < 0 || where >= Py_SIZE(self)) {
2384 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2385 return NULL;
2386 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002387 if (!_canresize(self))
2388 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002389
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002390 buf = PyByteArray_AS_STRING(self);
2391 value = buf[where];
2392 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002393 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2394 return NULL;
2395
Mark Dickinson54a3db92009-09-06 10:19:23 +00002396 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002397}
2398
2399PyDoc_STRVAR(remove__doc__,
2400"B.remove(int) -> None\n\
2401\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002402Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002403static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002404bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002405{
2406 int value;
2407 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002408 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002409
2410 if (! _getbytevalue(arg, &value))
2411 return NULL;
2412
2413 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002414 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002415 break;
2416 }
2417 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002418 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002419 return NULL;
2420 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002421 if (!_canresize(self))
2422 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002423
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002424 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002425 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2426 return NULL;
2427
2428 Py_RETURN_NONE;
2429}
2430
2431/* XXX These two helpers could be optimized if argsize == 1 */
2432
2433static Py_ssize_t
2434lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2435 void *argptr, Py_ssize_t argsize)
2436{
2437 Py_ssize_t i = 0;
2438 while (i < mysize && memchr(argptr, myptr[i], argsize))
2439 i++;
2440 return i;
2441}
2442
2443static Py_ssize_t
2444rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2445 void *argptr, Py_ssize_t argsize)
2446{
2447 Py_ssize_t i = mysize - 1;
2448 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2449 i--;
2450 return i + 1;
2451}
2452
2453PyDoc_STRVAR(strip__doc__,
2454"B.strip([bytes]) -> bytearray\n\
2455\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002456Strip leading and trailing bytes contained in the argument\n\
2457and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002458If the argument is omitted, strip ASCII whitespace.");
2459static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002460bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002461{
2462 Py_ssize_t left, right, mysize, argsize;
2463 void *myptr, *argptr;
2464 PyObject *arg = Py_None;
2465 Py_buffer varg;
2466 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2467 return NULL;
2468 if (arg == Py_None) {
2469 argptr = "\t\n\r\f\v ";
2470 argsize = 6;
2471 }
2472 else {
2473 if (_getbuffer(arg, &varg) < 0)
2474 return NULL;
2475 argptr = varg.buf;
2476 argsize = varg.len;
2477 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002478 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002479 mysize = Py_SIZE(self);
2480 left = lstrip_helper(myptr, mysize, argptr, argsize);
2481 if (left == mysize)
2482 right = left;
2483 else
2484 right = rstrip_helper(myptr, mysize, argptr, argsize);
2485 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002486 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002487 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002488}
2489
2490PyDoc_STRVAR(lstrip__doc__,
2491"B.lstrip([bytes]) -> bytearray\n\
2492\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002493Strip leading bytes contained in the argument\n\
2494and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002495If the argument is omitted, strip leading ASCII whitespace.");
2496static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002497bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002498{
2499 Py_ssize_t left, right, mysize, argsize;
2500 void *myptr, *argptr;
2501 PyObject *arg = Py_None;
2502 Py_buffer varg;
2503 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2504 return NULL;
2505 if (arg == Py_None) {
2506 argptr = "\t\n\r\f\v ";
2507 argsize = 6;
2508 }
2509 else {
2510 if (_getbuffer(arg, &varg) < 0)
2511 return NULL;
2512 argptr = varg.buf;
2513 argsize = varg.len;
2514 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002515 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002516 mysize = Py_SIZE(self);
2517 left = lstrip_helper(myptr, mysize, argptr, argsize);
2518 right = mysize;
2519 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002520 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002521 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002522}
2523
2524PyDoc_STRVAR(rstrip__doc__,
2525"B.rstrip([bytes]) -> bytearray\n\
2526\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002527Strip trailing bytes contained in the argument\n\
2528and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002529If the argument is omitted, strip trailing ASCII whitespace.");
2530static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002531bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002532{
Brett Cannonb94767f2011-02-22 20:15:44 +00002533 Py_ssize_t right, mysize, argsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002534 void *myptr, *argptr;
2535 PyObject *arg = Py_None;
2536 Py_buffer varg;
2537 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2538 return NULL;
2539 if (arg == Py_None) {
2540 argptr = "\t\n\r\f\v ";
2541 argsize = 6;
2542 }
2543 else {
2544 if (_getbuffer(arg, &varg) < 0)
2545 return NULL;
2546 argptr = varg.buf;
2547 argsize = varg.len;
2548 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002549 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002550 mysize = Py_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002551 right = rstrip_helper(myptr, mysize, argptr, argsize);
2552 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002553 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002554 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002555}
2556
2557PyDoc_STRVAR(decode_doc,
Victor Stinnerc911bbf2010-11-07 19:04:46 +00002558"B.decode(encoding='utf-8', errors='strict') -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002559\n\
Victor Stinnere14e2122010-11-07 18:41:46 +00002560Decode B using the codec registered for encoding. Default encoding\n\
2561is 'utf-8'. errors may be given to set a different error\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002562handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2563a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2564as well as any other name registered with codecs.register_error that is\n\
2565able to handle UnicodeDecodeErrors.");
2566
2567static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002568bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002569{
2570 const char *encoding = NULL;
2571 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002572 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002573
Benjamin Peterson308d6372009-09-18 21:42:35 +00002574 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002575 return NULL;
2576 if (encoding == NULL)
2577 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002578 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002579}
2580
2581PyDoc_STRVAR(alloc_doc,
2582"B.__alloc__() -> int\n\
2583\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002584Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002585
2586static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002587bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002588{
2589 return PyLong_FromSsize_t(self->ob_alloc);
2590}
2591
2592PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002593"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002594\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002595Concatenate any number of bytes/bytearray objects, with B\n\
2596in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002597
2598static PyObject *
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002599bytearray_join(PyObject *self, PyObject *iterable)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002600{
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002601 return stringlib_bytes_join(self, iterable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002602}
2603
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002604PyDoc_STRVAR(splitlines__doc__,
2605"B.splitlines([keepends]) -> list of lines\n\
2606\n\
2607Return a list of the lines in B, breaking at line boundaries.\n\
2608Line breaks are not included in the resulting list unless keepends\n\
2609is given and true.");
2610
2611static PyObject*
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002612bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002613{
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002614 static char *kwlist[] = {"keepends", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002615 int keepends = 0;
2616
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002617 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines",
2618 kwlist, &keepends))
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002619 return NULL;
2620
2621 return stringlib_splitlines(
2622 (PyObject*) self, PyByteArray_AS_STRING(self),
2623 PyByteArray_GET_SIZE(self), keepends
2624 );
2625}
2626
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002627PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002628"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002629\n\
2630Create a bytearray object from a string of hexadecimal numbers.\n\
2631Spaces between two numbers are accepted.\n\
2632Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2633
2634static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002635hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002636{
2637 if (c >= 128)
2638 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002639 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002640 return c - '0';
2641 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002642 if (Py_ISUPPER(c))
2643 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002644 if (c >= 'a' && c <= 'f')
2645 return c - 'a' + 10;
2646 }
2647 return -1;
2648}
2649
2650static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002651bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002652{
2653 PyObject *newbytes, *hexobj;
2654 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002655 Py_ssize_t hexlen, byteslen, i, j;
2656 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002657 void *data;
2658 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002659
2660 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2661 return NULL;
2662 assert(PyUnicode_Check(hexobj));
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002663 if (PyUnicode_READY(hexobj))
2664 return NULL;
2665 kind = PyUnicode_KIND(hexobj);
2666 data = PyUnicode_DATA(hexobj);
2667 hexlen = PyUnicode_GET_LENGTH(hexobj);
2668
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002669 byteslen = hexlen/2; /* This overestimates if there are spaces */
2670 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2671 if (!newbytes)
2672 return NULL;
2673 buf = PyByteArray_AS_STRING(newbytes);
2674 for (i = j = 0; i < hexlen; i += 2) {
2675 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002676 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002677 i++;
2678 if (i >= hexlen)
2679 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002680 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2681 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002682 if (top == -1 || bot == -1) {
2683 PyErr_Format(PyExc_ValueError,
2684 "non-hexadecimal number found in "
2685 "fromhex() arg at position %zd", i);
2686 goto error;
2687 }
2688 buf[j++] = (top << 4) + bot;
2689 }
2690 if (PyByteArray_Resize(newbytes, j) < 0)
2691 goto error;
2692 return newbytes;
2693
2694 error:
2695 Py_DECREF(newbytes);
2696 return NULL;
2697}
2698
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002699
2700static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002701_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002702{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002703 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002704 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002705 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002706
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002707 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002708 if (dict == NULL) {
2709 PyErr_Clear();
2710 dict = Py_None;
2711 Py_INCREF(dict);
2712 }
2713
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002714 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002715 if (proto < 3) {
2716 /* use str based reduction for backwards compatibility with Python 2.x */
2717 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002718 if (Py_SIZE(self))
2719 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002720 else
2721 latin1 = PyUnicode_FromString("");
2722 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2723 }
2724 else {
2725 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002726 if (Py_SIZE(self)) {
2727 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002728 }
2729 else {
2730 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2731 }
2732 }
2733}
2734
2735PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2736
2737static PyObject *
2738bytearray_reduce(PyByteArrayObject *self)
2739{
2740 return _common_reduce(self, 2);
2741}
2742
2743PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling.");
2744
2745static PyObject *
2746bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
2747{
2748 int proto = 0;
2749
2750 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
2751 return NULL;
2752
2753 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002754}
2755
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002756PyDoc_STRVAR(sizeof_doc,
2757"B.__sizeof__() -> int\n\
2758 \n\
2759Returns the size of B in memory, in bytes");
2760static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002761bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002762{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002763 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002764
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002765 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2766 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002767}
2768
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002769static PySequenceMethods bytearray_as_sequence = {
2770 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002771 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002772 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2773 (ssizeargfunc)bytearray_getitem, /* sq_item */
2774 0, /* sq_slice */
2775 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2776 0, /* sq_ass_slice */
2777 (objobjproc)bytearray_contains, /* sq_contains */
2778 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2779 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002780};
2781
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002782static PyMappingMethods bytearray_as_mapping = {
2783 (lenfunc)bytearray_length,
2784 (binaryfunc)bytearray_subscript,
2785 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002786};
2787
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002788static PyBufferProcs bytearray_as_buffer = {
2789 (getbufferproc)bytearray_getbuffer,
2790 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002791};
2792
2793static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002794bytearray_methods[] = {
2795 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2796 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002797 {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002798 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2799 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002800 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2801 _Py_capitalize__doc__},
2802 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00002803 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__},
2804 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002805 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002806 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002807 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002808 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2809 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002810 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2811 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2812 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002813 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002814 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2815 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002816 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2817 _Py_isalnum__doc__},
2818 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2819 _Py_isalpha__doc__},
2820 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2821 _Py_isdigit__doc__},
2822 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2823 _Py_islower__doc__},
2824 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2825 _Py_isspace__doc__},
2826 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2827 _Py_istitle__doc__},
2828 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2829 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002830 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002831 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2832 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002833 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2834 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002835 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002836 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2837 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2838 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2839 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2840 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2841 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2842 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002843 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002844 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002845 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002846 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002847 {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__},
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002848 {"splitlines", (PyCFunction)bytearray_splitlines,
2849 METH_VARARGS | METH_KEYWORDS, splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002850 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002851 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002852 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002853 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2854 _Py_swapcase__doc__},
2855 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002856 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002857 translate__doc__},
2858 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2859 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2860 {NULL}
2861};
2862
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002863PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002864"bytearray(iterable_of_ints) -> bytearray\n\
2865bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002866bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2867bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2868bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002869\n\
2870Construct an mutable bytearray object from:\n\
2871 - an iterable yielding integers in range(256)\n\
2872 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002873 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002874 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002875 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002876
2877
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002878static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002879
2880PyTypeObject PyByteArray_Type = {
2881 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2882 "bytearray",
2883 sizeof(PyByteArrayObject),
2884 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002885 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002886 0, /* tp_print */
2887 0, /* tp_getattr */
2888 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002889 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002890 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002891 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002892 &bytearray_as_sequence, /* tp_as_sequence */
2893 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002894 0, /* tp_hash */
2895 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002896 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002897 PyObject_GenericGetAttr, /* tp_getattro */
2898 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002899 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002900 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002901 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002902 0, /* tp_traverse */
2903 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002904 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002905 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002906 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002907 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002908 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002909 0, /* tp_members */
2910 0, /* tp_getset */
2911 0, /* tp_base */
2912 0, /* tp_dict */
2913 0, /* tp_descr_get */
2914 0, /* tp_descr_set */
2915 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002916 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002917 PyType_GenericAlloc, /* tp_alloc */
2918 PyType_GenericNew, /* tp_new */
2919 PyObject_Del, /* tp_free */
2920};
2921
2922/*********************** Bytes Iterator ****************************/
2923
2924typedef struct {
2925 PyObject_HEAD
2926 Py_ssize_t it_index;
2927 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2928} bytesiterobject;
2929
2930static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002931bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002932{
2933 _PyObject_GC_UNTRACK(it);
2934 Py_XDECREF(it->it_seq);
2935 PyObject_GC_Del(it);
2936}
2937
2938static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002939bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002940{
2941 Py_VISIT(it->it_seq);
2942 return 0;
2943}
2944
2945static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002946bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002947{
2948 PyByteArrayObject *seq;
2949 PyObject *item;
2950
2951 assert(it != NULL);
2952 seq = it->it_seq;
2953 if (seq == NULL)
2954 return NULL;
2955 assert(PyByteArray_Check(seq));
2956
2957 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2958 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002959 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002960 if (item != NULL)
2961 ++it->it_index;
2962 return item;
2963 }
2964
2965 Py_DECREF(seq);
2966 it->it_seq = NULL;
2967 return NULL;
2968}
2969
2970static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002971bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002972{
2973 Py_ssize_t len = 0;
2974 if (it->it_seq)
2975 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2976 return PyLong_FromSsize_t(len);
2977}
2978
2979PyDoc_STRVAR(length_hint_doc,
2980 "Private method returning an estimate of len(list(it)).");
2981
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002982static PyObject *
2983bytearrayiter_reduce(bytesiterobject *it)
2984{
2985 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02002986 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002987 it->it_seq, it->it_index);
2988 } else {
2989 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
2990 if (u == NULL)
2991 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02002992 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002993 }
2994}
2995
2996static PyObject *
2997bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
2998{
2999 Py_ssize_t index = PyLong_AsSsize_t(state);
3000 if (index == -1 && PyErr_Occurred())
3001 return NULL;
3002 if (index < 0)
3003 index = 0;
3004 it->it_index = index;
3005 Py_RETURN_NONE;
3006}
3007
3008PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3009
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003010static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003011 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003012 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003013 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
3014 reduce_doc},
3015 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3016 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003017 {NULL, NULL} /* sentinel */
3018};
3019
3020PyTypeObject PyByteArrayIter_Type = {
3021 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3022 "bytearray_iterator", /* tp_name */
3023 sizeof(bytesiterobject), /* tp_basicsize */
3024 0, /* tp_itemsize */
3025 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003026 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003027 0, /* tp_print */
3028 0, /* tp_getattr */
3029 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003030 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003031 0, /* tp_repr */
3032 0, /* tp_as_number */
3033 0, /* tp_as_sequence */
3034 0, /* tp_as_mapping */
3035 0, /* tp_hash */
3036 0, /* tp_call */
3037 0, /* tp_str */
3038 PyObject_GenericGetAttr, /* tp_getattro */
3039 0, /* tp_setattro */
3040 0, /* tp_as_buffer */
3041 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3042 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003043 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003044 0, /* tp_clear */
3045 0, /* tp_richcompare */
3046 0, /* tp_weaklistoffset */
3047 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003048 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3049 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003050 0,
3051};
3052
3053static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003054bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003055{
3056 bytesiterobject *it;
3057
3058 if (!PyByteArray_Check(seq)) {
3059 PyErr_BadInternalCall();
3060 return NULL;
3061 }
3062 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3063 if (it == NULL)
3064 return NULL;
3065 it->it_index = 0;
3066 Py_INCREF(seq);
3067 it->it_seq = (PyByteArrayObject *)seq;
3068 _PyObject_GC_TRACK(it);
3069 return (PyObject *)it;
3070}