blob: 31cc4ccebdc37f72878a9a79abc61c9374e370d3 [file] [log] [blame]
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001/* PyByteArray (bytearray) implementation */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
5#include "structmember.h"
6#include "bytes_methods.h"
7
Antoine Pitroufc8d6f42010-01-17 12:38:54 +00008char _PyByteArray_empty_string[] = "";
Christian Heimes2c9c7a52008-05-26 13:42:13 +00009
10void
11PyByteArray_Fini(void)
12{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000013}
14
15int
16PyByteArray_Init(void)
17{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000018 return 1;
19}
20
21/* end nullbytes support */
22
23/* Helpers */
24
25static int
26_getbytevalue(PyObject* arg, int *value)
27{
28 long face_value;
29
30 if (PyLong_Check(arg)) {
31 face_value = PyLong_AsLong(arg);
Georg Brandl9a54d7c2008-07-16 23:15:30 +000032 } else {
33 PyObject *index = PyNumber_Index(arg);
34 if (index == NULL) {
35 PyErr_Format(PyExc_TypeError, "an integer is required");
Mark Dickinson10de93a2010-07-09 19:25:48 +000036 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000037 return 0;
38 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +000039 face_value = PyLong_AsLong(index);
40 Py_DECREF(index);
41 }
42
43 if (face_value < 0 || face_value >= 256) {
44 /* this includes the OverflowError in case the long is too large */
45 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Mark Dickinson10de93a2010-07-09 19:25:48 +000046 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000047 return 0;
48 }
49
50 *value = face_value;
51 return 1;
52}
53
54static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +000055bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000056{
57 int ret;
58 void *ptr;
59 if (view == NULL) {
60 obj->ob_exports++;
61 return 0;
62 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000063 ptr = (void *) PyByteArray_AS_STRING(obj);
Martin v. Löwis423be952008-08-13 15:53:07 +000064 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
Christian Heimes2c9c7a52008-05-26 13:42:13 +000065 if (ret >= 0) {
66 obj->ob_exports++;
67 }
68 return ret;
69}
70
71static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +000072bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000073{
74 obj->ob_exports--;
75}
76
77static Py_ssize_t
78_getbuffer(PyObject *obj, Py_buffer *view)
79{
80 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
81
82 if (buffer == NULL || buffer->bf_getbuffer == NULL)
83 {
84 PyErr_Format(PyExc_TypeError,
85 "Type %.100s doesn't support the buffer API",
86 Py_TYPE(obj)->tp_name);
87 return -1;
88 }
89
90 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
91 return -1;
92 return view->len;
93}
94
Antoine Pitrou5504e892008-12-06 21:27:53 +000095static int
96_canresize(PyByteArrayObject *self)
97{
98 if (self->ob_exports > 0) {
99 PyErr_SetString(PyExc_BufferError,
100 "Existing exports of data: object cannot be re-sized");
101 return 0;
102 }
103 return 1;
104}
105
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000106/* Direct API functions */
107
108PyObject *
109PyByteArray_FromObject(PyObject *input)
110{
111 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
112 input, NULL);
113}
114
115PyObject *
116PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
117{
118 PyByteArrayObject *new;
119 Py_ssize_t alloc;
120
121 if (size < 0) {
122 PyErr_SetString(PyExc_SystemError,
123 "Negative size passed to PyByteArray_FromStringAndSize");
124 return NULL;
125 }
126
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000127 /* Prevent buffer overflow when setting alloc to size+1. */
128 if (size == PY_SSIZE_T_MAX) {
129 return PyErr_NoMemory();
130 }
131
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000132 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
133 if (new == NULL)
134 return NULL;
135
136 if (size == 0) {
137 new->ob_bytes = NULL;
138 alloc = 0;
139 }
140 else {
141 alloc = size + 1;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100142 new->ob_bytes = PyObject_Malloc(alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000143 if (new->ob_bytes == NULL) {
144 Py_DECREF(new);
145 return PyErr_NoMemory();
146 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +0000147 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000148 memcpy(new->ob_bytes, bytes, size);
149 new->ob_bytes[size] = '\0'; /* Trailing null byte */
150 }
151 Py_SIZE(new) = size;
152 new->ob_alloc = alloc;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200153 new->ob_start = new->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000154 new->ob_exports = 0;
155
156 return (PyObject *)new;
157}
158
159Py_ssize_t
160PyByteArray_Size(PyObject *self)
161{
162 assert(self != NULL);
163 assert(PyByteArray_Check(self));
164
165 return PyByteArray_GET_SIZE(self);
166}
167
168char *
169PyByteArray_AsString(PyObject *self)
170{
171 assert(self != NULL);
172 assert(PyByteArray_Check(self));
173
174 return PyByteArray_AS_STRING(self);
175}
176
177int
178PyByteArray_Resize(PyObject *self, Py_ssize_t size)
179{
180 void *sval;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200181 PyByteArrayObject *obj = ((PyByteArrayObject *)self);
182 Py_ssize_t alloc = obj->ob_alloc;
183 Py_ssize_t logical_offset = obj->ob_start - obj->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000184
185 assert(self != NULL);
186 assert(PyByteArray_Check(self));
187 assert(size >= 0);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200188 assert(logical_offset >= 0);
189 assert(logical_offset <= alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000190
Antoine Pitrou5504e892008-12-06 21:27:53 +0000191 if (size == Py_SIZE(self)) {
192 return 0;
193 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200194 if (!_canresize(obj)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000195 return -1;
196 }
197
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200198 if (size + logical_offset + 1 < alloc) {
199 /* Current buffer is large enough to host the requested size,
200 decide on a strategy. */
201 if (size < alloc / 2) {
202 /* Major downsize; resize down to exact size */
203 alloc = size + 1;
204 }
205 else {
206 /* Minor downsize; quick exit */
207 Py_SIZE(self) = size;
208 PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
209 return 0;
210 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000211 }
212 else {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200213 /* Need growing, decide on a strategy */
214 if (size <= alloc * 1.125) {
215 /* Moderate upsize; overallocate similar to list_resize() */
216 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
217 }
218 else {
219 /* Major upsize; resize up to exact size */
220 alloc = size + 1;
221 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000222 }
223
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200224 if (logical_offset > 0) {
225 sval = PyObject_Malloc(alloc);
226 if (sval == NULL) {
227 PyErr_NoMemory();
228 return -1;
229 }
230 memcpy(sval, PyByteArray_AS_STRING(self), Py_MIN(size, Py_SIZE(self)));
231 PyObject_Free(obj->ob_bytes);
232 }
233 else {
234 sval = PyObject_Realloc(obj->ob_bytes, alloc);
235 if (sval == NULL) {
236 PyErr_NoMemory();
237 return -1;
238 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000239 }
240
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200241 obj->ob_bytes = obj->ob_start = sval;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000242 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200243 obj->ob_alloc = alloc;
244 obj->ob_bytes[size] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000245
246 return 0;
247}
248
249PyObject *
250PyByteArray_Concat(PyObject *a, PyObject *b)
251{
252 Py_ssize_t size;
253 Py_buffer va, vb;
254 PyByteArrayObject *result = NULL;
255
256 va.len = -1;
257 vb.len = -1;
258 if (_getbuffer(a, &va) < 0 ||
259 _getbuffer(b, &vb) < 0) {
260 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
261 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
262 goto done;
263 }
264
265 size = va.len + vb.len;
266 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000267 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000268 goto done;
269 }
270
271 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
272 if (result != NULL) {
273 memcpy(result->ob_bytes, va.buf, va.len);
274 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
275 }
276
277 done:
278 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000279 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000280 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000281 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000282 return (PyObject *)result;
283}
284
285/* Functions stuffed into the type object */
286
287static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000288bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000289{
290 return Py_SIZE(self);
291}
292
293static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000294bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000295{
296 Py_ssize_t mysize;
297 Py_ssize_t size;
298 Py_buffer vo;
299
300 if (_getbuffer(other, &vo) < 0) {
301 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
302 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
303 return NULL;
304 }
305
306 mysize = Py_SIZE(self);
307 size = mysize + vo.len;
308 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000309 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000310 return PyErr_NoMemory();
311 }
312 if (size < self->ob_alloc) {
313 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200314 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000315 }
316 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000317 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000318 return NULL;
319 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200320 memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000321 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000322 Py_INCREF(self);
323 return (PyObject *)self;
324}
325
326static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000327bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000328{
329 PyByteArrayObject *result;
330 Py_ssize_t mysize;
331 Py_ssize_t size;
332
333 if (count < 0)
334 count = 0;
335 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000336 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000337 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000338 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000339 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
340 if (result != NULL && size != 0) {
341 if (mysize == 1)
342 memset(result->ob_bytes, self->ob_bytes[0], size);
343 else {
344 Py_ssize_t i;
345 for (i = 0; i < count; i++)
346 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
347 }
348 }
349 return (PyObject *)result;
350}
351
352static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000353bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000354{
355 Py_ssize_t mysize;
356 Py_ssize_t size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200357 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000358
359 if (count < 0)
360 count = 0;
361 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000362 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000363 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000364 size = mysize * count;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200365 if (PyByteArray_Resize((PyObject *)self, size) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000366 return NULL;
367
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200368 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000369 if (mysize == 1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200370 memset(buf, buf[0], size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000371 else {
372 Py_ssize_t i;
373 for (i = 1; i < count; i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200374 memcpy(buf + i*mysize, buf, mysize);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000375 }
376
377 Py_INCREF(self);
378 return (PyObject *)self;
379}
380
381static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000382bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000383{
384 if (i < 0)
385 i += Py_SIZE(self);
386 if (i < 0 || i >= Py_SIZE(self)) {
387 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
388 return NULL;
389 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200390 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000391}
392
393static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000394bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000395{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000396 if (PyIndex_Check(index)) {
397 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000398
399 if (i == -1 && PyErr_Occurred())
400 return NULL;
401
402 if (i < 0)
403 i += PyByteArray_GET_SIZE(self);
404
405 if (i < 0 || i >= Py_SIZE(self)) {
406 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
407 return NULL;
408 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200409 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000410 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000411 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000412 Py_ssize_t start, stop, step, slicelength, cur, i;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000413 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000414 PyByteArray_GET_SIZE(self),
415 &start, &stop, &step, &slicelength) < 0) {
416 return NULL;
417 }
418
419 if (slicelength <= 0)
420 return PyByteArray_FromStringAndSize("", 0);
421 else if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200422 return PyByteArray_FromStringAndSize(
423 PyByteArray_AS_STRING(self) + start, slicelength);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000424 }
425 else {
426 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000427 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000428 PyObject *result;
429
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000430 result = PyByteArray_FromStringAndSize(NULL, slicelength);
431 if (result == NULL)
432 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000433
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000434 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000435 for (cur = start, i = 0; i < slicelength;
436 cur += step, i++) {
437 result_buf[i] = source_buf[cur];
438 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000439 return result;
440 }
441 }
442 else {
443 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
444 return NULL;
445 }
446}
447
448static int
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200449bytearray_setslice_linear(PyByteArrayObject *self,
450 Py_ssize_t lo, Py_ssize_t hi,
451 char *bytes, Py_ssize_t bytes_len)
452{
453 Py_ssize_t avail = hi - lo;
454 char *buf = PyByteArray_AS_STRING(self);
455 Py_ssize_t growth = bytes_len - avail;
Victor Stinner84557232013-11-21 12:29:51 +0100456 int res = 0;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200457 assert(avail >= 0);
458
Victor Stinner84557232013-11-21 12:29:51 +0100459 if (growth < 0) {
460 if (!_canresize(self))
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200461 return -1;
Victor Stinner84557232013-11-21 12:29:51 +0100462
463 if (lo == 0) {
464 /* Shrink the buffer by advancing its logical start */
465 self->ob_start -= growth;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200466 /*
Victor Stinner84557232013-11-21 12:29:51 +0100467 0 lo hi old_size
468 | |<----avail----->|<-----tail------>|
469 | |<-bytes_len->|<-----tail------>|
470 0 new_lo new_hi new_size
471 */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200472 }
Victor Stinner84557232013-11-21 12:29:51 +0100473 else {
474 /*
475 0 lo hi old_size
476 | |<----avail----->|<-----tomove------>|
477 | |<-bytes_len->|<-----tomove------>|
478 0 lo new_hi new_size
479 */
480 memmove(buf + lo + bytes_len, buf + hi,
481 Py_SIZE(self) - hi);
482 }
483 if (PyByteArray_Resize((PyObject *)self,
484 Py_SIZE(self) + growth) < 0) {
485 /* Issue #19578: Handling the memory allocation failure here is
486 tricky here because the bytearray object has already been
487 modified. Depending on growth and lo, the behaviour is
488 different.
489
490 If growth < 0 and lo != 0, the operation is completed, but a
491 MemoryError is still raised and the memory block is not
492 shrinked. Otherwise, the bytearray is restored in its previous
493 state and a MemoryError is raised. */
494 if (lo == 0) {
495 self->ob_start += growth;
496 return -1;
497 }
498 /* memmove() removed bytes, the bytearray object cannot be
499 restored in its previous state. */
500 Py_SIZE(self) += growth;
501 res = -1;
502 }
503 buf = PyByteArray_AS_STRING(self);
504 }
505 else if (growth > 0) {
506 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
507 PyErr_NoMemory();
508 return -1;
509 }
510
511 if (PyByteArray_Resize((PyObject *)self,
512 Py_SIZE(self) + growth) < 0) {
513 return -1;
514 }
515 buf = PyByteArray_AS_STRING(self);
516 /* Make the place for the additional bytes */
517 /*
518 0 lo hi old_size
519 | |<-avail->|<-----tomove------>|
520 | |<---bytes_len-->|<-----tomove------>|
521 0 lo new_hi new_size
522 */
523 memmove(buf + lo + bytes_len, buf + hi,
524 Py_SIZE(self) - lo - bytes_len);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200525 }
526
527 if (bytes_len > 0)
528 memcpy(buf + lo, bytes, bytes_len);
Victor Stinner84557232013-11-21 12:29:51 +0100529 return res;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200530}
531
532static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000533bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000534 PyObject *values)
535{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200536 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000537 void *bytes;
538 Py_buffer vbytes;
539 int res = 0;
540
541 vbytes.len = -1;
542 if (values == (PyObject *)self) {
543 /* Make a copy and call this function recursively */
544 int err;
545 values = PyByteArray_FromObject(values);
546 if (values == NULL)
547 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000548 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000549 Py_DECREF(values);
550 return err;
551 }
552 if (values == NULL) {
553 /* del b[lo:hi] */
554 bytes = NULL;
555 needed = 0;
556 }
557 else {
558 if (_getbuffer(values, &vbytes) < 0) {
559 PyErr_Format(PyExc_TypeError,
Georg Brandl3dbca812008-07-23 16:10:53 +0000560 "can't set bytearray slice from %.100s",
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000561 Py_TYPE(values)->tp_name);
562 return -1;
563 }
564 needed = vbytes.len;
565 bytes = vbytes.buf;
566 }
567
568 if (lo < 0)
569 lo = 0;
570 if (hi < lo)
571 hi = lo;
572 if (hi > Py_SIZE(self))
573 hi = Py_SIZE(self);
574
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200575 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000576 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200577 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000578 return res;
579}
580
581static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000582bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000583{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000584 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000585
586 if (i < 0)
587 i += Py_SIZE(self);
588
589 if (i < 0 || i >= Py_SIZE(self)) {
590 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
591 return -1;
592 }
593
594 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000595 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000596
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000597 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000598 return -1;
599
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200600 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000601 return 0;
602}
603
604static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000605bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000606{
607 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200608 char *buf, *bytes;
609 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000610
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000611 if (PyIndex_Check(index)) {
612 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000613
614 if (i == -1 && PyErr_Occurred())
615 return -1;
616
617 if (i < 0)
618 i += PyByteArray_GET_SIZE(self);
619
620 if (i < 0 || i >= Py_SIZE(self)) {
621 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
622 return -1;
623 }
624
625 if (values == NULL) {
626 /* Fall through to slice assignment */
627 start = i;
628 stop = i + 1;
629 step = 1;
630 slicelen = 1;
631 }
632 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000633 int ival;
634 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000635 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200636 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000637 return 0;
638 }
639 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000640 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000641 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000642 PyByteArray_GET_SIZE(self),
643 &start, &stop, &step, &slicelen) < 0) {
644 return -1;
645 }
646 }
647 else {
648 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
649 return -1;
650 }
651
652 if (values == NULL) {
653 bytes = NULL;
654 needed = 0;
655 }
656 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100657 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200658 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
659 PyErr_SetString(PyExc_TypeError,
660 "can assign only bytes, buffers, or iterables "
661 "of ints in range(0, 256)");
662 return -1;
663 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000664 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000665 values = PyByteArray_FromObject(values);
666 if (values == NULL)
667 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000668 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000669 Py_DECREF(values);
670 return err;
671 }
672 else {
673 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200674 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000675 needed = Py_SIZE(values);
676 }
677 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
678 if ((step < 0 && start < stop) ||
679 (step > 0 && start > stop))
680 stop = start;
681 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200682 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000683 }
684 else {
685 if (needed == 0) {
686 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000687 size_t cur;
688 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000689
Antoine Pitrou5504e892008-12-06 21:27:53 +0000690 if (!_canresize(self))
691 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000692
693 if (slicelen == 0)
694 /* Nothing to do here. */
695 return 0;
696
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000697 if (step < 0) {
698 stop = start + 1;
699 start = stop + step * (slicelen - 1) - 1;
700 step = -step;
701 }
702 for (cur = start, i = 0;
703 i < slicelen; cur += step, i++) {
704 Py_ssize_t lim = step - 1;
705
Mark Dickinson66f575b2010-02-14 12:53:32 +0000706 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000707 lim = PyByteArray_GET_SIZE(self) - cur - 1;
708
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200709 memmove(buf + cur - i,
710 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000711 }
712 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000713 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000714 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200715 memmove(buf + cur - slicelen,
716 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000717 PyByteArray_GET_SIZE(self) - cur);
718 }
719 if (PyByteArray_Resize((PyObject *)self,
720 PyByteArray_GET_SIZE(self) - slicelen) < 0)
721 return -1;
722
723 return 0;
724 }
725 else {
726 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000727 Py_ssize_t i;
728 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000729
730 if (needed != slicelen) {
731 PyErr_Format(PyExc_ValueError,
732 "attempt to assign bytes of size %zd "
733 "to extended slice of size %zd",
734 needed, slicelen);
735 return -1;
736 }
737 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200738 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000739 return 0;
740 }
741 }
742}
743
744static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000745bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000746{
747 static char *kwlist[] = {"source", "encoding", "errors", 0};
748 PyObject *arg = NULL;
749 const char *encoding = NULL;
750 const char *errors = NULL;
751 Py_ssize_t count;
752 PyObject *it;
753 PyObject *(*iternext)(PyObject *);
754
755 if (Py_SIZE(self) != 0) {
756 /* Empty previous contents (yes, do this first of all!) */
757 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
758 return -1;
759 }
760
761 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000762 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000763 &arg, &encoding, &errors))
764 return -1;
765
766 /* Make a quick exit if no first argument */
767 if (arg == NULL) {
768 if (encoding != NULL || errors != NULL) {
769 PyErr_SetString(PyExc_TypeError,
770 "encoding or errors without sequence argument");
771 return -1;
772 }
773 return 0;
774 }
775
776 if (PyUnicode_Check(arg)) {
777 /* Encode via the codec registry */
778 PyObject *encoded, *new;
779 if (encoding == NULL) {
780 PyErr_SetString(PyExc_TypeError,
781 "string argument without an encoding");
782 return -1;
783 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000784 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000785 if (encoded == NULL)
786 return -1;
787 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000788 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000789 Py_DECREF(encoded);
790 if (new == NULL)
791 return -1;
792 Py_DECREF(new);
793 return 0;
794 }
795
796 /* If it's not unicode, there can't be encoding or errors */
797 if (encoding != NULL || errors != NULL) {
798 PyErr_SetString(PyExc_TypeError,
799 "encoding or errors without a string argument");
800 return -1;
801 }
802
803 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000804 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
805 if (count == -1 && PyErr_Occurred()) {
806 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000807 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000808 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000809 }
810 else if (count < 0) {
811 PyErr_SetString(PyExc_ValueError, "negative count");
812 return -1;
813 }
814 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000815 if (count > 0) {
816 if (PyByteArray_Resize((PyObject *)self, count))
817 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200818 memset(PyByteArray_AS_STRING(self), 0, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000819 }
820 return 0;
821 }
822
823 /* Use the buffer API */
824 if (PyObject_CheckBuffer(arg)) {
825 Py_ssize_t size;
826 Py_buffer view;
827 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
828 return -1;
829 size = view.len;
830 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200831 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
832 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200833 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000834 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000835 return 0;
836 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000837 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000838 return -1;
839 }
840
841 /* XXX Optimize this if the arguments is a list, tuple */
842
843 /* Get the iterator */
844 it = PyObject_GetIter(arg);
845 if (it == NULL)
846 return -1;
847 iternext = *Py_TYPE(it)->tp_iternext;
848
849 /* Run the iterator to exhaustion */
850 for (;;) {
851 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000852 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000853
854 /* Get the next item */
855 item = iternext(it);
856 if (item == NULL) {
857 if (PyErr_Occurred()) {
858 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
859 goto error;
860 PyErr_Clear();
861 }
862 break;
863 }
864
865 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000866 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000867 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000868 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000869 goto error;
870
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000871 /* Append the byte */
872 if (Py_SIZE(self) < self->ob_alloc)
873 Py_SIZE(self)++;
874 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
875 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200876 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000877 }
878
879 /* Clean up and return success */
880 Py_DECREF(it);
881 return 0;
882
883 error:
884 /* Error handling when it != NULL */
885 Py_DECREF(it);
886 return -1;
887}
888
889/* Mostly copied from string_repr, but without the
890 "smart quote" functionality. */
891static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000892bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000893{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000894 const char *quote_prefix = "bytearray(b";
895 const char *quote_postfix = ")";
896 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200897 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000898 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000899 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200900 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200901 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200902 char c;
903 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200904 int quote;
905 char *test, *start;
906 char *buffer;
907
908 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000909 PyErr_SetString(PyExc_OverflowError,
910 "bytearray object is too large to make repr");
911 return NULL;
912 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200913
914 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100915 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200916 if (buffer == NULL) {
917 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000918 return NULL;
919 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000920
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200921 /* Figure out which quote to use; single is preferred */
922 quote = '\'';
923 start = PyByteArray_AS_STRING(self);
924 for (test = start; test < start+length; ++test) {
925 if (*test == '"') {
926 quote = '\''; /* back to single */
927 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000928 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200929 else if (*test == '\'')
930 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000931 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200932
933 p = buffer;
934 while (*quote_prefix)
935 *p++ = *quote_prefix++;
936 *p++ = quote;
937
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200938 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200939 for (i = 0; i < length; i++) {
940 /* There's at least enough room for a hex escape
941 and a closing quote. */
942 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200943 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200944 if (c == '\'' || c == '\\')
945 *p++ = '\\', *p++ = c;
946 else if (c == '\t')
947 *p++ = '\\', *p++ = 't';
948 else if (c == '\n')
949 *p++ = '\\', *p++ = 'n';
950 else if (c == '\r')
951 *p++ = '\\', *p++ = 'r';
952 else if (c == 0)
953 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
954 else if (c < ' ' || c >= 0x7f) {
955 *p++ = '\\';
956 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200957 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
958 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200959 }
960 else
961 *p++ = c;
962 }
963 assert(newsize - (p - buffer) >= 1);
964 *p++ = quote;
965 while (*quote_postfix) {
966 *p++ = *quote_postfix++;
967 }
968
969 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100970 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200971 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000972}
973
974static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000975bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000976{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000977 if (Py_BytesWarningFlag) {
978 if (PyErr_WarnEx(PyExc_BytesWarning,
979 "str() on a bytearray instance", 1))
980 return NULL;
981 }
982 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000983}
984
985static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000986bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000987{
988 Py_ssize_t self_size, other_size;
989 Py_buffer self_bytes, other_bytes;
990 PyObject *res;
991 Py_ssize_t minsize;
992 int cmp;
993
994 /* Bytes can be compared to anything that supports the (binary)
995 buffer API. Except that a comparison with Unicode is always an
996 error, even if the comparison is for equality. */
997 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
998 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000999 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001000 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +00001001 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001002 return NULL;
1003 }
1004
Brian Curtindfc80e32011-08-10 20:28:54 -05001005 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001006 }
1007
1008 self_size = _getbuffer(self, &self_bytes);
1009 if (self_size < 0) {
1010 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -05001011 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001012 }
1013
1014 other_size = _getbuffer(other, &other_bytes);
1015 if (other_size < 0) {
1016 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001017 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001018 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001019 }
1020
1021 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1022 /* Shortcut: if the lengths differ, the objects differ */
1023 cmp = (op == Py_NE);
1024 }
1025 else {
1026 minsize = self_size;
1027 if (other_size < minsize)
1028 minsize = other_size;
1029
1030 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1031 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1032
1033 if (cmp == 0) {
1034 if (self_size < other_size)
1035 cmp = -1;
1036 else if (self_size > other_size)
1037 cmp = 1;
1038 }
1039
1040 switch (op) {
1041 case Py_LT: cmp = cmp < 0; break;
1042 case Py_LE: cmp = cmp <= 0; break;
1043 case Py_EQ: cmp = cmp == 0; break;
1044 case Py_NE: cmp = cmp != 0; break;
1045 case Py_GT: cmp = cmp > 0; break;
1046 case Py_GE: cmp = cmp >= 0; break;
1047 }
1048 }
1049
1050 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001051 PyBuffer_Release(&self_bytes);
1052 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001053 Py_INCREF(res);
1054 return res;
1055}
1056
1057static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001058bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001059{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001060 if (self->ob_exports > 0) {
1061 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001062 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001063 PyErr_Print();
1064 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001065 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001066 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001067 }
1068 Py_TYPE(self)->tp_free((PyObject *)self);
1069}
1070
1071
1072/* -------------------------------------------------------------------- */
1073/* Methods */
1074
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001075#define FASTSEARCH fastsearch
1076#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001077#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001078#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001079#define STRINGLIB_LEN PyByteArray_GET_SIZE
1080#define STRINGLIB_STR PyByteArray_AS_STRING
1081#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001082#define STRINGLIB_ISSPACE Py_ISSPACE
1083#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001084#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1085#define STRINGLIB_MUTABLE 1
1086
1087#include "stringlib/fastsearch.h"
1088#include "stringlib/count.h"
1089#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001090#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001091#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001092#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001093#include "stringlib/ctype.h"
1094#include "stringlib/transmogrify.h"
1095
1096
1097/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1098were copied from the old char* style string object. */
1099
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001100/* helper macro to fixup start/end slice values */
1101#define ADJUST_INDICES(start, end, len) \
1102 if (end > len) \
1103 end = len; \
1104 else if (end < 0) { \
1105 end += len; \
1106 if (end < 0) \
1107 end = 0; \
1108 } \
1109 if (start < 0) { \
1110 start += len; \
1111 if (start < 0) \
1112 start = 0; \
1113 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001114
1115Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001116bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001117{
1118 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001119 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001120 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001121 const char *sub;
1122 Py_ssize_t sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001123 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1124 Py_ssize_t res;
1125
Antoine Pitrouac65d962011-10-20 23:54:17 +02001126 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1127 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001128 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001129
1130 if (subobj) {
1131 if (_getbuffer(subobj, &subbuf) < 0)
1132 return -2;
1133
1134 sub = subbuf.buf;
1135 sub_len = subbuf.len;
1136 }
1137 else {
1138 sub = &byte;
1139 sub_len = 1;
1140 }
1141
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001142 if (dir > 0)
1143 res = stringlib_find_slice(
1144 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001145 sub, sub_len, start, end);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001146 else
1147 res = stringlib_rfind_slice(
1148 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001149 sub, sub_len, start, end);
1150
1151 if (subobj)
1152 PyBuffer_Release(&subbuf);
1153
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001154 return res;
1155}
1156
1157PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001158"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001159\n\
1160Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001161such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001162arguments start and end are interpreted as in slice notation.\n\
1163\n\
1164Return -1 on failure.");
1165
1166static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001167bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001168{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001169 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001170 if (result == -2)
1171 return NULL;
1172 return PyLong_FromSsize_t(result);
1173}
1174
1175PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001176"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001177\n\
1178Return the number of non-overlapping occurrences of subsection sub in\n\
1179bytes B[start:end]. Optional arguments start and end are interpreted\n\
1180as in slice notation.");
1181
1182static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001183bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001184{
1185 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001186 const char *str = PyByteArray_AS_STRING(self), *sub;
1187 Py_ssize_t sub_len;
1188 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001189 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001190
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001191 Py_buffer vsub;
1192 PyObject *count_obj;
1193
Antoine Pitrouac65d962011-10-20 23:54:17 +02001194 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1195 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001196 return NULL;
1197
Antoine Pitrouac65d962011-10-20 23:54:17 +02001198 if (sub_obj) {
1199 if (_getbuffer(sub_obj, &vsub) < 0)
1200 return NULL;
1201
1202 sub = vsub.buf;
1203 sub_len = vsub.len;
1204 }
1205 else {
1206 sub = &byte;
1207 sub_len = 1;
1208 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001209
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001210 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001211
1212 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001213 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001214 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001215
1216 if (sub_obj)
1217 PyBuffer_Release(&vsub);
1218
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001219 return count_obj;
1220}
1221
Eli Bendersky4db28d32011-03-03 18:21:02 +00001222PyDoc_STRVAR(clear__doc__,
1223"B.clear() -> None\n\
1224\n\
1225Remove all items from B.");
1226
Victor Stinner6430fd52011-09-29 04:02:13 +02001227static PyObject *
Eli Bendersky4db28d32011-03-03 18:21:02 +00001228bytearray_clear(PyByteArrayObject *self)
1229{
1230 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1231 return NULL;
1232 Py_RETURN_NONE;
1233}
1234
1235PyDoc_STRVAR(copy__doc__,
1236"B.copy() -> bytearray\n\
1237\n\
1238Return a copy of B.");
1239
1240static PyObject *
1241bytearray_copy(PyByteArrayObject *self)
1242{
1243 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1244 PyByteArray_GET_SIZE(self));
1245}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001246
1247PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001248"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001249\n\
1250Like B.find() but raise ValueError when the subsection is not found.");
1251
1252static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001253bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001254{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001255 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001256 if (result == -2)
1257 return NULL;
1258 if (result == -1) {
1259 PyErr_SetString(PyExc_ValueError,
1260 "subsection not found");
1261 return NULL;
1262 }
1263 return PyLong_FromSsize_t(result);
1264}
1265
1266
1267PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001268"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001269\n\
1270Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001271such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001272arguments start and end are interpreted as in slice notation.\n\
1273\n\
1274Return -1 on failure.");
1275
1276static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001277bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001278{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001279 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001280 if (result == -2)
1281 return NULL;
1282 return PyLong_FromSsize_t(result);
1283}
1284
1285
1286PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001287"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001288\n\
1289Like B.rfind() but raise ValueError when the subsection is not found.");
1290
1291static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001292bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001293{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001294 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001295 if (result == -2)
1296 return NULL;
1297 if (result == -1) {
1298 PyErr_SetString(PyExc_ValueError,
1299 "subsection not found");
1300 return NULL;
1301 }
1302 return PyLong_FromSsize_t(result);
1303}
1304
1305
1306static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001307bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001308{
1309 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1310 if (ival == -1 && PyErr_Occurred()) {
1311 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001312 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001313 PyErr_Clear();
1314 if (_getbuffer(arg, &varg) < 0)
1315 return -1;
1316 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1317 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001318 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001319 return pos >= 0;
1320 }
1321 if (ival < 0 || ival >= 256) {
1322 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1323 return -1;
1324 }
1325
Antoine Pitrou0010d372010-08-15 17:12:55 +00001326 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001327}
1328
1329
1330/* Matches the end (direction >= 0) or start (direction < 0) of self
1331 * against substr, using the start and end arguments. Returns
1332 * -1 on error, 0 if not found and 1 if found.
1333 */
1334Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001335_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001336 Py_ssize_t end, int direction)
1337{
1338 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1339 const char* str;
1340 Py_buffer vsubstr;
1341 int rv = 0;
1342
1343 str = PyByteArray_AS_STRING(self);
1344
1345 if (_getbuffer(substr, &vsubstr) < 0)
1346 return -1;
1347
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001348 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001349
1350 if (direction < 0) {
1351 /* startswith */
1352 if (start+vsubstr.len > len) {
1353 goto done;
1354 }
1355 } else {
1356 /* endswith */
1357 if (end-start < vsubstr.len || start > len) {
1358 goto done;
1359 }
1360
1361 if (end-vsubstr.len > start)
1362 start = end - vsubstr.len;
1363 }
1364 if (end-start >= vsubstr.len)
1365 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1366
1367done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001368 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001369 return rv;
1370}
1371
1372
1373PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001374"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001375\n\
1376Return True if B starts with the specified prefix, False otherwise.\n\
1377With optional start, test B beginning at that position.\n\
1378With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001379prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001380
1381static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001382bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001383{
1384 Py_ssize_t start = 0;
1385 Py_ssize_t end = PY_SSIZE_T_MAX;
1386 PyObject *subobj;
1387 int result;
1388
Jesus Ceaac451502011-04-20 17:09:23 +02001389 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001390 return NULL;
1391 if (PyTuple_Check(subobj)) {
1392 Py_ssize_t i;
1393 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001394 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001395 PyTuple_GET_ITEM(subobj, i),
1396 start, end, -1);
1397 if (result == -1)
1398 return NULL;
1399 else if (result) {
1400 Py_RETURN_TRUE;
1401 }
1402 }
1403 Py_RETURN_FALSE;
1404 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001405 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001406 if (result == -1) {
1407 if (PyErr_ExceptionMatches(PyExc_TypeError))
1408 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1409 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001410 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001411 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001412 else
1413 return PyBool_FromLong(result);
1414}
1415
1416PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001417"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001418\n\
1419Return True if B ends with the specified suffix, False otherwise.\n\
1420With optional start, test B beginning at that position.\n\
1421With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001422suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001423
1424static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001425bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001426{
1427 Py_ssize_t start = 0;
1428 Py_ssize_t end = PY_SSIZE_T_MAX;
1429 PyObject *subobj;
1430 int result;
1431
Jesus Ceaac451502011-04-20 17:09:23 +02001432 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001433 return NULL;
1434 if (PyTuple_Check(subobj)) {
1435 Py_ssize_t i;
1436 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001437 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001438 PyTuple_GET_ITEM(subobj, i),
1439 start, end, +1);
1440 if (result == -1)
1441 return NULL;
1442 else if (result) {
1443 Py_RETURN_TRUE;
1444 }
1445 }
1446 Py_RETURN_FALSE;
1447 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001448 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001449 if (result == -1) {
1450 if (PyErr_ExceptionMatches(PyExc_TypeError))
1451 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1452 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001453 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001454 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001455 else
1456 return PyBool_FromLong(result);
1457}
1458
1459
1460PyDoc_STRVAR(translate__doc__,
1461"B.translate(table[, deletechars]) -> bytearray\n\
1462\n\
1463Return a copy of B, where all characters occurring in the\n\
1464optional argument deletechars are removed, and the remaining\n\
1465characters have been mapped through the given translation\n\
1466table, which must be a bytes object of length 256.");
1467
1468static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001469bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001470{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001471 char *input, *output;
1472 const char *table;
1473 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001474 PyObject *input_obj = (PyObject*)self;
1475 const char *output_start;
1476 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001477 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001478 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001479 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001480 Py_buffer vtable, vdel;
1481
1482 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1483 &tableobj, &delobj))
1484 return NULL;
1485
Georg Brandlccc47b62008-12-28 11:44:14 +00001486 if (tableobj == Py_None) {
1487 table = NULL;
1488 tableobj = NULL;
1489 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001490 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001491 } else {
1492 if (vtable.len != 256) {
1493 PyErr_SetString(PyExc_ValueError,
1494 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001495 PyBuffer_Release(&vtable);
1496 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001497 }
1498 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001499 }
1500
1501 if (delobj != NULL) {
1502 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001503 if (tableobj != NULL)
1504 PyBuffer_Release(&vtable);
1505 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001506 }
1507 }
1508 else {
1509 vdel.buf = NULL;
1510 vdel.len = 0;
1511 }
1512
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001513 inlen = PyByteArray_GET_SIZE(input_obj);
1514 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1515 if (result == NULL)
1516 goto done;
1517 output_start = output = PyByteArray_AsString(result);
1518 input = PyByteArray_AS_STRING(input_obj);
1519
Georg Brandlccc47b62008-12-28 11:44:14 +00001520 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001521 /* If no deletions are required, use faster code */
1522 for (i = inlen; --i >= 0; ) {
1523 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001524 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001525 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001526 goto done;
1527 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001528
1529 if (table == NULL) {
1530 for (i = 0; i < 256; i++)
1531 trans_table[i] = Py_CHARMASK(i);
1532 } else {
1533 for (i = 0; i < 256; i++)
1534 trans_table[i] = Py_CHARMASK(table[i]);
1535 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001536
1537 for (i = 0; i < vdel.len; i++)
1538 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1539
1540 for (i = inlen; --i >= 0; ) {
1541 c = Py_CHARMASK(*input++);
1542 if (trans_table[c] != -1)
1543 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1544 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001545 }
1546 /* Fix the size of the resulting string */
1547 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001548 if (PyByteArray_Resize(result, output - output_start) < 0) {
1549 Py_CLEAR(result);
1550 goto done;
1551 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001552
1553done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001554 if (tableobj != NULL)
1555 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001556 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001557 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001558 return result;
1559}
1560
1561
Georg Brandlabc38772009-04-12 15:51:51 +00001562static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001563bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001564{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001565 return _Py_bytes_maketrans(args);
Georg Brandlabc38772009-04-12 15:51:51 +00001566}
1567
1568
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001569/* find and count characters and substrings */
1570
1571#define findchar(target, target_len, c) \
1572 ((char *)memchr((const void *)(target), c, target_len))
1573
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001574
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001575/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001576Py_LOCAL(PyByteArrayObject *)
1577return_self(PyByteArrayObject *self)
1578{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001579 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001580 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1581 PyByteArray_AS_STRING(self),
1582 PyByteArray_GET_SIZE(self));
1583}
1584
1585Py_LOCAL_INLINE(Py_ssize_t)
1586countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1587{
1588 Py_ssize_t count=0;
1589 const char *start=target;
1590 const char *end=target+target_len;
1591
1592 while ( (start=findchar(start, end-start, c)) != NULL ) {
1593 count++;
1594 if (count >= maxcount)
1595 break;
1596 start += 1;
1597 }
1598 return count;
1599}
1600
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001601
1602/* Algorithms for different cases of string replacement */
1603
1604/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1605Py_LOCAL(PyByteArrayObject *)
1606replace_interleave(PyByteArrayObject *self,
1607 const char *to_s, Py_ssize_t to_len,
1608 Py_ssize_t maxcount)
1609{
1610 char *self_s, *result_s;
1611 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001612 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001613 PyByteArrayObject *result;
1614
1615 self_len = PyByteArray_GET_SIZE(self);
1616
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001617 /* 1 at the end plus 1 after every character;
1618 count = min(maxcount, self_len + 1) */
1619 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001620 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001621 else
1622 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1623 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001624
1625 /* Check for overflow */
1626 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001627 assert(count > 0);
1628 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001629 PyErr_SetString(PyExc_OverflowError,
1630 "replace string is too long");
1631 return NULL;
1632 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001633 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001634
1635 if (! (result = (PyByteArrayObject *)
1636 PyByteArray_FromStringAndSize(NULL, result_len)) )
1637 return NULL;
1638
1639 self_s = PyByteArray_AS_STRING(self);
1640 result_s = PyByteArray_AS_STRING(result);
1641
1642 /* TODO: special case single character, which doesn't need memcpy */
1643
1644 /* Lay the first one down (guaranteed this will occur) */
1645 Py_MEMCPY(result_s, to_s, to_len);
1646 result_s += to_len;
1647 count -= 1;
1648
1649 for (i=0; i<count; i++) {
1650 *result_s++ = *self_s++;
1651 Py_MEMCPY(result_s, to_s, to_len);
1652 result_s += to_len;
1653 }
1654
1655 /* Copy the rest of the original string */
1656 Py_MEMCPY(result_s, self_s, self_len-i);
1657
1658 return result;
1659}
1660
1661/* Special case for deleting a single character */
1662/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1663Py_LOCAL(PyByteArrayObject *)
1664replace_delete_single_character(PyByteArrayObject *self,
1665 char from_c, Py_ssize_t maxcount)
1666{
1667 char *self_s, *result_s;
1668 char *start, *next, *end;
1669 Py_ssize_t self_len, result_len;
1670 Py_ssize_t count;
1671 PyByteArrayObject *result;
1672
1673 self_len = PyByteArray_GET_SIZE(self);
1674 self_s = PyByteArray_AS_STRING(self);
1675
1676 count = countchar(self_s, self_len, from_c, maxcount);
1677 if (count == 0) {
1678 return return_self(self);
1679 }
1680
1681 result_len = self_len - count; /* from_len == 1 */
1682 assert(result_len>=0);
1683
1684 if ( (result = (PyByteArrayObject *)
1685 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1686 return NULL;
1687 result_s = PyByteArray_AS_STRING(result);
1688
1689 start = self_s;
1690 end = self_s + self_len;
1691 while (count-- > 0) {
1692 next = findchar(start, end-start, from_c);
1693 if (next == NULL)
1694 break;
1695 Py_MEMCPY(result_s, start, next-start);
1696 result_s += (next-start);
1697 start = next+1;
1698 }
1699 Py_MEMCPY(result_s, start, end-start);
1700
1701 return result;
1702}
1703
1704/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1705
1706Py_LOCAL(PyByteArrayObject *)
1707replace_delete_substring(PyByteArrayObject *self,
1708 const char *from_s, Py_ssize_t from_len,
1709 Py_ssize_t maxcount)
1710{
1711 char *self_s, *result_s;
1712 char *start, *next, *end;
1713 Py_ssize_t self_len, result_len;
1714 Py_ssize_t count, offset;
1715 PyByteArrayObject *result;
1716
1717 self_len = PyByteArray_GET_SIZE(self);
1718 self_s = PyByteArray_AS_STRING(self);
1719
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001720 count = stringlib_count(self_s, self_len,
1721 from_s, from_len,
1722 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001723
1724 if (count == 0) {
1725 /* no matches */
1726 return return_self(self);
1727 }
1728
1729 result_len = self_len - (count * from_len);
1730 assert (result_len>=0);
1731
1732 if ( (result = (PyByteArrayObject *)
1733 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1734 return NULL;
1735
1736 result_s = PyByteArray_AS_STRING(result);
1737
1738 start = self_s;
1739 end = self_s + self_len;
1740 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001741 offset = stringlib_find(start, end-start,
1742 from_s, from_len,
1743 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001744 if (offset == -1)
1745 break;
1746 next = start + offset;
1747
1748 Py_MEMCPY(result_s, start, next-start);
1749
1750 result_s += (next-start);
1751 start = next+from_len;
1752 }
1753 Py_MEMCPY(result_s, start, end-start);
1754 return result;
1755}
1756
1757/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1758Py_LOCAL(PyByteArrayObject *)
1759replace_single_character_in_place(PyByteArrayObject *self,
1760 char from_c, char to_c,
1761 Py_ssize_t maxcount)
1762{
Antoine Pitroud1188562010-06-09 16:38:55 +00001763 char *self_s, *result_s, *start, *end, *next;
1764 Py_ssize_t self_len;
1765 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001766
Antoine Pitroud1188562010-06-09 16:38:55 +00001767 /* The result string will be the same size */
1768 self_s = PyByteArray_AS_STRING(self);
1769 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001770
Antoine Pitroud1188562010-06-09 16:38:55 +00001771 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001772
Antoine Pitroud1188562010-06-09 16:38:55 +00001773 if (next == NULL) {
1774 /* No matches; return the original bytes */
1775 return return_self(self);
1776 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001777
Antoine Pitroud1188562010-06-09 16:38:55 +00001778 /* Need to make a new bytes */
1779 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1780 if (result == NULL)
1781 return NULL;
1782 result_s = PyByteArray_AS_STRING(result);
1783 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001784
Antoine Pitroud1188562010-06-09 16:38:55 +00001785 /* change everything in-place, starting with this one */
1786 start = result_s + (next-self_s);
1787 *start = to_c;
1788 start++;
1789 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001790
Antoine Pitroud1188562010-06-09 16:38:55 +00001791 while (--maxcount > 0) {
1792 next = findchar(start, end-start, from_c);
1793 if (next == NULL)
1794 break;
1795 *next = to_c;
1796 start = next+1;
1797 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001798
Antoine Pitroud1188562010-06-09 16:38:55 +00001799 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001800}
1801
1802/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1803Py_LOCAL(PyByteArrayObject *)
1804replace_substring_in_place(PyByteArrayObject *self,
1805 const char *from_s, Py_ssize_t from_len,
1806 const char *to_s, Py_ssize_t to_len,
1807 Py_ssize_t maxcount)
1808{
1809 char *result_s, *start, *end;
1810 char *self_s;
1811 Py_ssize_t self_len, offset;
1812 PyByteArrayObject *result;
1813
1814 /* The result bytes will be the same size */
1815
1816 self_s = PyByteArray_AS_STRING(self);
1817 self_len = PyByteArray_GET_SIZE(self);
1818
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001819 offset = stringlib_find(self_s, self_len,
1820 from_s, from_len,
1821 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001822 if (offset == -1) {
1823 /* No matches; return the original bytes */
1824 return return_self(self);
1825 }
1826
1827 /* Need to make a new bytes */
1828 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1829 if (result == NULL)
1830 return NULL;
1831 result_s = PyByteArray_AS_STRING(result);
1832 Py_MEMCPY(result_s, self_s, self_len);
1833
1834 /* change everything in-place, starting with this one */
1835 start = result_s + offset;
1836 Py_MEMCPY(start, to_s, from_len);
1837 start += from_len;
1838 end = result_s + self_len;
1839
1840 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001841 offset = stringlib_find(start, end-start,
1842 from_s, from_len,
1843 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001844 if (offset==-1)
1845 break;
1846 Py_MEMCPY(start+offset, to_s, from_len);
1847 start += offset+from_len;
1848 }
1849
1850 return result;
1851}
1852
1853/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1854Py_LOCAL(PyByteArrayObject *)
1855replace_single_character(PyByteArrayObject *self,
1856 char from_c,
1857 const char *to_s, Py_ssize_t to_len,
1858 Py_ssize_t maxcount)
1859{
1860 char *self_s, *result_s;
1861 char *start, *next, *end;
1862 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001863 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001864 PyByteArrayObject *result;
1865
1866 self_s = PyByteArray_AS_STRING(self);
1867 self_len = PyByteArray_GET_SIZE(self);
1868
1869 count = countchar(self_s, self_len, from_c, maxcount);
1870 if (count == 0) {
1871 /* no matches, return unchanged */
1872 return return_self(self);
1873 }
1874
1875 /* use the difference between current and new, hence the "-1" */
1876 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001877 assert(count > 0);
1878 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001879 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1880 return NULL;
1881 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001882 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001883
1884 if ( (result = (PyByteArrayObject *)
1885 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1886 return NULL;
1887 result_s = PyByteArray_AS_STRING(result);
1888
1889 start = self_s;
1890 end = self_s + self_len;
1891 while (count-- > 0) {
1892 next = findchar(start, end-start, from_c);
1893 if (next == NULL)
1894 break;
1895
1896 if (next == start) {
1897 /* replace with the 'to' */
1898 Py_MEMCPY(result_s, to_s, to_len);
1899 result_s += to_len;
1900 start += 1;
1901 } else {
1902 /* copy the unchanged old then the 'to' */
1903 Py_MEMCPY(result_s, start, next-start);
1904 result_s += (next-start);
1905 Py_MEMCPY(result_s, to_s, to_len);
1906 result_s += to_len;
1907 start = next+1;
1908 }
1909 }
1910 /* Copy the remainder of the remaining bytes */
1911 Py_MEMCPY(result_s, start, end-start);
1912
1913 return result;
1914}
1915
1916/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1917Py_LOCAL(PyByteArrayObject *)
1918replace_substring(PyByteArrayObject *self,
1919 const char *from_s, Py_ssize_t from_len,
1920 const char *to_s, Py_ssize_t to_len,
1921 Py_ssize_t maxcount)
1922{
1923 char *self_s, *result_s;
1924 char *start, *next, *end;
1925 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001926 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001927 PyByteArrayObject *result;
1928
1929 self_s = PyByteArray_AS_STRING(self);
1930 self_len = PyByteArray_GET_SIZE(self);
1931
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001932 count = stringlib_count(self_s, self_len,
1933 from_s, from_len,
1934 maxcount);
1935
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001936 if (count == 0) {
1937 /* no matches, return unchanged */
1938 return return_self(self);
1939 }
1940
1941 /* Check for overflow */
1942 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001943 assert(count > 0);
1944 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001945 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1946 return NULL;
1947 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001948 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001949
1950 if ( (result = (PyByteArrayObject *)
1951 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1952 return NULL;
1953 result_s = PyByteArray_AS_STRING(result);
1954
1955 start = self_s;
1956 end = self_s + self_len;
1957 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001958 offset = stringlib_find(start, end-start,
1959 from_s, from_len,
1960 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001961 if (offset == -1)
1962 break;
1963 next = start+offset;
1964 if (next == start) {
1965 /* replace with the 'to' */
1966 Py_MEMCPY(result_s, to_s, to_len);
1967 result_s += to_len;
1968 start += from_len;
1969 } else {
1970 /* copy the unchanged old then the 'to' */
1971 Py_MEMCPY(result_s, start, next-start);
1972 result_s += (next-start);
1973 Py_MEMCPY(result_s, to_s, to_len);
1974 result_s += to_len;
1975 start = next+from_len;
1976 }
1977 }
1978 /* Copy the remainder of the remaining bytes */
1979 Py_MEMCPY(result_s, start, end-start);
1980
1981 return result;
1982}
1983
1984
1985Py_LOCAL(PyByteArrayObject *)
1986replace(PyByteArrayObject *self,
1987 const char *from_s, Py_ssize_t from_len,
1988 const char *to_s, Py_ssize_t to_len,
1989 Py_ssize_t maxcount)
1990{
1991 if (maxcount < 0) {
1992 maxcount = PY_SSIZE_T_MAX;
1993 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1994 /* nothing to do; return the original bytes */
1995 return return_self(self);
1996 }
1997
1998 if (maxcount == 0 ||
1999 (from_len == 0 && to_len == 0)) {
2000 /* nothing to do; return the original bytes */
2001 return return_self(self);
2002 }
2003
2004 /* Handle zero-length special cases */
2005
2006 if (from_len == 0) {
2007 /* insert the 'to' bytes everywhere. */
2008 /* >>> "Python".replace("", ".") */
2009 /* '.P.y.t.h.o.n.' */
2010 return replace_interleave(self, to_s, to_len, maxcount);
2011 }
2012
2013 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2014 /* point for an empty self bytes to generate a non-empty bytes */
2015 /* Special case so the remaining code always gets a non-empty bytes */
2016 if (PyByteArray_GET_SIZE(self) == 0) {
2017 return return_self(self);
2018 }
2019
2020 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002021 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002022 if (from_len == 1) {
2023 return replace_delete_single_character(
2024 self, from_s[0], maxcount);
2025 } else {
2026 return replace_delete_substring(self, from_s, from_len, maxcount);
2027 }
2028 }
2029
2030 /* Handle special case where both bytes have the same length */
2031
2032 if (from_len == to_len) {
2033 if (from_len == 1) {
2034 return replace_single_character_in_place(
2035 self,
2036 from_s[0],
2037 to_s[0],
2038 maxcount);
2039 } else {
2040 return replace_substring_in_place(
2041 self, from_s, from_len, to_s, to_len, maxcount);
2042 }
2043 }
2044
2045 /* Otherwise use the more generic algorithms */
2046 if (from_len == 1) {
2047 return replace_single_character(self, from_s[0],
2048 to_s, to_len, maxcount);
2049 } else {
2050 /* len('from')>=2, len('to')>=1 */
2051 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2052 }
2053}
2054
2055
2056PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002057"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002058\n\
2059Return a copy of B with all occurrences of subsection\n\
2060old replaced by new. If the optional argument count is\n\
2061given, only the first count occurrences are replaced.");
2062
2063static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002064bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002065{
2066 Py_ssize_t count = -1;
2067 PyObject *from, *to, *res;
2068 Py_buffer vfrom, vto;
2069
2070 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2071 return NULL;
2072
2073 if (_getbuffer(from, &vfrom) < 0)
2074 return NULL;
2075 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +00002076 PyBuffer_Release(&vfrom);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002077 return NULL;
2078 }
2079
2080 res = (PyObject *)replace((PyByteArrayObject *) self,
2081 vfrom.buf, vfrom.len,
2082 vto.buf, vto.len, count);
2083
Martin v. Löwis423be952008-08-13 15:53:07 +00002084 PyBuffer_Release(&vfrom);
2085 PyBuffer_Release(&vto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002086 return res;
2087}
2088
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002089PyDoc_STRVAR(split__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002090"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002091\n\
2092Return a list of the sections in B, using sep as the delimiter.\n\
2093If sep is not given, B is split on ASCII whitespace characters\n\
2094(space, tab, return, newline, formfeed, vertical tab).\n\
2095If maxsplit is given, at most maxsplit splits are done.");
2096
2097static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002098bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002099{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002100 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002101 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2102 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002103 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002104 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002105 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002106
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002107 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
2108 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002109 return NULL;
2110 if (maxsplit < 0)
2111 maxsplit = PY_SSIZE_T_MAX;
2112
2113 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002114 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002115
2116 if (_getbuffer(subobj, &vsub) < 0)
2117 return NULL;
2118 sub = vsub.buf;
2119 n = vsub.len;
2120
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002121 list = stringlib_split(
2122 (PyObject*) self, s, len, sub, n, maxsplit
2123 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002124 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002125 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002126}
2127
2128PyDoc_STRVAR(partition__doc__,
2129"B.partition(sep) -> (head, sep, tail)\n\
2130\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002131Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002132the separator itself, and the part after it. If the separator is not\n\
2133found, returns B and two empty bytearray objects.");
2134
2135static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002136bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002137{
2138 PyObject *bytesep, *result;
2139
2140 bytesep = PyByteArray_FromObject(sep_obj);
2141 if (! bytesep)
2142 return NULL;
2143
2144 result = stringlib_partition(
2145 (PyObject*) self,
2146 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2147 bytesep,
2148 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2149 );
2150
2151 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002152 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002153}
2154
2155PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002156"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002157\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002158Search for the separator sep in B, starting at the end of B,\n\
2159and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002160part after it. If the separator is not found, returns two empty\n\
2161bytearray objects and B.");
2162
2163static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002164bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002165{
2166 PyObject *bytesep, *result;
2167
2168 bytesep = PyByteArray_FromObject(sep_obj);
2169 if (! bytesep)
2170 return NULL;
2171
2172 result = stringlib_rpartition(
2173 (PyObject*) self,
2174 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2175 bytesep,
2176 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2177 );
2178
2179 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002180 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002181}
2182
2183PyDoc_STRVAR(rsplit__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002184"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002185\n\
2186Return a list of the sections in B, using sep as the delimiter,\n\
2187starting at the end of B and working to the front.\n\
2188If sep is not given, B is split on ASCII whitespace characters\n\
2189(space, tab, return, newline, formfeed, vertical tab).\n\
2190If maxsplit is given, at most maxsplit splits are done.");
2191
2192static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002193bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002194{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002195 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002196 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2197 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002198 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002199 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002200 Py_buffer vsub;
2201
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002202 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit",
2203 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002204 return NULL;
2205 if (maxsplit < 0)
2206 maxsplit = PY_SSIZE_T_MAX;
2207
2208 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002209 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002210
2211 if (_getbuffer(subobj, &vsub) < 0)
2212 return NULL;
2213 sub = vsub.buf;
2214 n = vsub.len;
2215
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002216 list = stringlib_rsplit(
2217 (PyObject*) self, s, len, sub, n, maxsplit
2218 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002219 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002220 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002221}
2222
2223PyDoc_STRVAR(reverse__doc__,
2224"B.reverse() -> None\n\
2225\n\
2226Reverse the order of the values in B in place.");
2227static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002228bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002229{
2230 char swap, *head, *tail;
2231 Py_ssize_t i, j, n = Py_SIZE(self);
2232
2233 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002234 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002235 tail = head + n - 1;
2236 for (i = 0; i < j; i++) {
2237 swap = *head;
2238 *head++ = *tail;
2239 *tail-- = swap;
2240 }
2241
2242 Py_RETURN_NONE;
2243}
2244
2245PyDoc_STRVAR(insert__doc__,
2246"B.insert(index, int) -> None\n\
2247\n\
2248Insert a single item into the bytearray before the given index.");
2249static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002250bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002251{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002252 PyObject *value;
2253 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002254 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002255 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002256
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002257 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002258 return NULL;
2259
2260 if (n == PY_SSIZE_T_MAX) {
2261 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002262 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002263 return NULL;
2264 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002265 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002266 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002267 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2268 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002269 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002270
2271 if (where < 0) {
2272 where += n;
2273 if (where < 0)
2274 where = 0;
2275 }
2276 if (where > n)
2277 where = n;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002278 memmove(buf + where + 1, buf + where, n - where);
2279 buf[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002280
2281 Py_RETURN_NONE;
2282}
2283
2284PyDoc_STRVAR(append__doc__,
2285"B.append(int) -> None\n\
2286\n\
2287Append a single item to the end of B.");
2288static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002289bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002290{
2291 int value;
2292 Py_ssize_t n = Py_SIZE(self);
2293
2294 if (! _getbytevalue(arg, &value))
2295 return NULL;
2296 if (n == PY_SSIZE_T_MAX) {
2297 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002298 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002299 return NULL;
2300 }
2301 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2302 return NULL;
2303
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002304 PyByteArray_AS_STRING(self)[n] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002305
2306 Py_RETURN_NONE;
2307}
2308
2309PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002310"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002311\n\
2312Append all the elements from the iterator or sequence to the\n\
2313end of B.");
2314static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002315bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002316{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002317 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002318 Py_ssize_t buf_size = 0, len = 0;
2319 int value;
2320 char *buf;
2321
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002322 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002323 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002324 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002325 return NULL;
2326
2327 Py_RETURN_NONE;
2328 }
2329
2330 it = PyObject_GetIter(arg);
2331 if (it == NULL)
2332 return NULL;
2333
Ezio Melotti42da6632011-03-15 05:18:48 +02002334 /* Try to determine the length of the argument. 32 is arbitrary. */
Armin Ronacheraa9a79d2012-10-06 14:03:24 +02002335 buf_size = PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002336 if (buf_size == -1) {
2337 Py_DECREF(it);
2338 return NULL;
2339 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002340
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002341 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002342 if (bytearray_obj == NULL) {
2343 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002344 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002345 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002346 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002347
2348 while ((item = PyIter_Next(it)) != NULL) {
2349 if (! _getbytevalue(item, &value)) {
2350 Py_DECREF(item);
2351 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002352 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002353 return NULL;
2354 }
2355 buf[len++] = value;
2356 Py_DECREF(item);
2357
2358 if (len >= buf_size) {
2359 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002360 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002361 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002362 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002363 return NULL;
2364 }
2365 /* Recompute the `buf' pointer, since the resizing operation may
2366 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002367 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002368 }
2369 }
2370 Py_DECREF(it);
2371
2372 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002373 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2374 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002375 return NULL;
2376 }
2377
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002378 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2379 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002380 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002381 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002382 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002383
2384 Py_RETURN_NONE;
2385}
2386
2387PyDoc_STRVAR(pop__doc__,
2388"B.pop([index]) -> int\n\
2389\n\
2390Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002391argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002392static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002393bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002394{
2395 int value;
2396 Py_ssize_t where = -1, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002397 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002398
2399 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2400 return NULL;
2401
2402 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002403 PyErr_SetString(PyExc_IndexError,
2404 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002405 return NULL;
2406 }
2407 if (where < 0)
2408 where += Py_SIZE(self);
2409 if (where < 0 || where >= Py_SIZE(self)) {
2410 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2411 return NULL;
2412 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002413 if (!_canresize(self))
2414 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002415
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002416 buf = PyByteArray_AS_STRING(self);
2417 value = buf[where];
2418 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002419 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2420 return NULL;
2421
Mark Dickinson54a3db92009-09-06 10:19:23 +00002422 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002423}
2424
2425PyDoc_STRVAR(remove__doc__,
2426"B.remove(int) -> None\n\
2427\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002428Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002429static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002430bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002431{
2432 int value;
2433 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002434 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002435
2436 if (! _getbytevalue(arg, &value))
2437 return NULL;
2438
2439 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002440 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002441 break;
2442 }
2443 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002444 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002445 return NULL;
2446 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002447 if (!_canresize(self))
2448 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002449
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002450 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002451 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2452 return NULL;
2453
2454 Py_RETURN_NONE;
2455}
2456
2457/* XXX These two helpers could be optimized if argsize == 1 */
2458
2459static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002460lstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002461 void *argptr, Py_ssize_t argsize)
2462{
2463 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002464 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002465 i++;
2466 return i;
2467}
2468
2469static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002470rstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002471 void *argptr, Py_ssize_t argsize)
2472{
2473 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002474 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002475 i--;
2476 return i + 1;
2477}
2478
2479PyDoc_STRVAR(strip__doc__,
2480"B.strip([bytes]) -> bytearray\n\
2481\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002482Strip leading and trailing bytes contained in the argument\n\
2483and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002484If the argument is omitted, strip ASCII whitespace.");
2485static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002486bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002487{
2488 Py_ssize_t left, right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002489 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002490 PyObject *arg = Py_None;
2491 Py_buffer varg;
2492 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2493 return NULL;
2494 if (arg == Py_None) {
2495 argptr = "\t\n\r\f\v ";
2496 argsize = 6;
2497 }
2498 else {
2499 if (_getbuffer(arg, &varg) < 0)
2500 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002501 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002502 argsize = varg.len;
2503 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002504 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002505 mysize = Py_SIZE(self);
2506 left = lstrip_helper(myptr, mysize, argptr, argsize);
2507 if (left == mysize)
2508 right = left;
2509 else
2510 right = rstrip_helper(myptr, mysize, argptr, argsize);
2511 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002512 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002513 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002514}
2515
2516PyDoc_STRVAR(lstrip__doc__,
2517"B.lstrip([bytes]) -> bytearray\n\
2518\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002519Strip leading bytes contained in the argument\n\
2520and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002521If the argument is omitted, strip leading ASCII whitespace.");
2522static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002523bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002524{
2525 Py_ssize_t left, right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002526 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002527 PyObject *arg = Py_None;
2528 Py_buffer varg;
2529 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2530 return NULL;
2531 if (arg == Py_None) {
2532 argptr = "\t\n\r\f\v ";
2533 argsize = 6;
2534 }
2535 else {
2536 if (_getbuffer(arg, &varg) < 0)
2537 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002538 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002539 argsize = varg.len;
2540 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002541 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002542 mysize = Py_SIZE(self);
2543 left = lstrip_helper(myptr, mysize, argptr, argsize);
2544 right = mysize;
2545 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002546 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002547 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002548}
2549
2550PyDoc_STRVAR(rstrip__doc__,
2551"B.rstrip([bytes]) -> bytearray\n\
2552\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002553Strip trailing bytes contained in the argument\n\
2554and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002555If the argument is omitted, strip trailing ASCII whitespace.");
2556static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002557bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002558{
Brett Cannonb94767f2011-02-22 20:15:44 +00002559 Py_ssize_t right, mysize, argsize;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002560 char *myptr, *argptr;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002561 PyObject *arg = Py_None;
2562 Py_buffer varg;
2563 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2564 return NULL;
2565 if (arg == Py_None) {
2566 argptr = "\t\n\r\f\v ";
2567 argsize = 6;
2568 }
2569 else {
2570 if (_getbuffer(arg, &varg) < 0)
2571 return NULL;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002572 argptr = (char *) varg.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002573 argsize = varg.len;
2574 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002575 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002576 mysize = Py_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002577 right = rstrip_helper(myptr, mysize, argptr, argsize);
2578 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002579 PyBuffer_Release(&varg);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002580 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002581}
2582
2583PyDoc_STRVAR(decode_doc,
Victor Stinnerc911bbf2010-11-07 19:04:46 +00002584"B.decode(encoding='utf-8', errors='strict') -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002585\n\
Victor Stinnere14e2122010-11-07 18:41:46 +00002586Decode B using the codec registered for encoding. Default encoding\n\
2587is 'utf-8'. errors may be given to set a different error\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002588handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2589a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2590as well as any other name registered with codecs.register_error that is\n\
2591able to handle UnicodeDecodeErrors.");
2592
2593static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002594bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002595{
2596 const char *encoding = NULL;
2597 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002598 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002599
Benjamin Peterson308d6372009-09-18 21:42:35 +00002600 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002601 return NULL;
2602 if (encoding == NULL)
2603 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002604 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002605}
2606
2607PyDoc_STRVAR(alloc_doc,
2608"B.__alloc__() -> int\n\
2609\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002610Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002611
2612static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002613bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002614{
2615 return PyLong_FromSsize_t(self->ob_alloc);
2616}
2617
2618PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002619"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002620\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002621Concatenate any number of bytes/bytearray objects, with B\n\
2622in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002623
2624static PyObject *
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002625bytearray_join(PyObject *self, PyObject *iterable)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002626{
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002627 return stringlib_bytes_join(self, iterable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002628}
2629
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002630PyDoc_STRVAR(splitlines__doc__,
2631"B.splitlines([keepends]) -> list of lines\n\
2632\n\
2633Return a list of the lines in B, breaking at line boundaries.\n\
2634Line breaks are not included in the resulting list unless keepends\n\
2635is given and true.");
2636
2637static PyObject*
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002638bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002639{
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002640 static char *kwlist[] = {"keepends", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002641 int keepends = 0;
2642
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002643 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines",
2644 kwlist, &keepends))
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002645 return NULL;
2646
2647 return stringlib_splitlines(
2648 (PyObject*) self, PyByteArray_AS_STRING(self),
2649 PyByteArray_GET_SIZE(self), keepends
2650 );
2651}
2652
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002653PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002654"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002655\n\
2656Create a bytearray object from a string of hexadecimal numbers.\n\
2657Spaces between two numbers are accepted.\n\
2658Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2659
2660static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002661hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002662{
2663 if (c >= 128)
2664 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002665 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002666 return c - '0';
2667 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002668 if (Py_ISUPPER(c))
2669 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002670 if (c >= 'a' && c <= 'f')
2671 return c - 'a' + 10;
2672 }
2673 return -1;
2674}
2675
2676static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002677bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002678{
2679 PyObject *newbytes, *hexobj;
2680 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002681 Py_ssize_t hexlen, byteslen, i, j;
2682 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002683 void *data;
2684 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002685
2686 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2687 return NULL;
2688 assert(PyUnicode_Check(hexobj));
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002689 if (PyUnicode_READY(hexobj))
2690 return NULL;
2691 kind = PyUnicode_KIND(hexobj);
2692 data = PyUnicode_DATA(hexobj);
2693 hexlen = PyUnicode_GET_LENGTH(hexobj);
2694
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002695 byteslen = hexlen/2; /* This overestimates if there are spaces */
2696 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2697 if (!newbytes)
2698 return NULL;
2699 buf = PyByteArray_AS_STRING(newbytes);
2700 for (i = j = 0; i < hexlen; i += 2) {
2701 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002702 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002703 i++;
2704 if (i >= hexlen)
2705 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002706 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2707 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002708 if (top == -1 || bot == -1) {
2709 PyErr_Format(PyExc_ValueError,
2710 "non-hexadecimal number found in "
2711 "fromhex() arg at position %zd", i);
2712 goto error;
2713 }
2714 buf[j++] = (top << 4) + bot;
2715 }
2716 if (PyByteArray_Resize(newbytes, j) < 0)
2717 goto error;
2718 return newbytes;
2719
2720 error:
2721 Py_DECREF(newbytes);
2722 return NULL;
2723}
2724
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002725
2726static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002727_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002728{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002729 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002730 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002731 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002732
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002733 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002734 if (dict == NULL) {
2735 PyErr_Clear();
2736 dict = Py_None;
2737 Py_INCREF(dict);
2738 }
2739
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002740 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002741 if (proto < 3) {
2742 /* use str based reduction for backwards compatibility with Python 2.x */
2743 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002744 if (Py_SIZE(self))
2745 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002746 else
2747 latin1 = PyUnicode_FromString("");
2748 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2749 }
2750 else {
2751 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002752 if (Py_SIZE(self)) {
2753 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002754 }
2755 else {
2756 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2757 }
2758 }
2759}
2760
2761PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2762
2763static PyObject *
2764bytearray_reduce(PyByteArrayObject *self)
2765{
2766 return _common_reduce(self, 2);
2767}
2768
2769PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling.");
2770
2771static PyObject *
2772bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
2773{
2774 int proto = 0;
2775
2776 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
2777 return NULL;
2778
2779 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002780}
2781
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002782PyDoc_STRVAR(sizeof_doc,
2783"B.__sizeof__() -> int\n\
2784 \n\
2785Returns the size of B in memory, in bytes");
2786static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002787bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002788{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002789 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002790
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002791 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2792 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002793}
2794
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002795static PySequenceMethods bytearray_as_sequence = {
2796 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002797 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002798 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2799 (ssizeargfunc)bytearray_getitem, /* sq_item */
2800 0, /* sq_slice */
2801 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2802 0, /* sq_ass_slice */
2803 (objobjproc)bytearray_contains, /* sq_contains */
2804 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2805 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002806};
2807
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002808static PyMappingMethods bytearray_as_mapping = {
2809 (lenfunc)bytearray_length,
2810 (binaryfunc)bytearray_subscript,
2811 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002812};
2813
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002814static PyBufferProcs bytearray_as_buffer = {
2815 (getbufferproc)bytearray_getbuffer,
2816 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002817};
2818
2819static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002820bytearray_methods[] = {
2821 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2822 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002823 {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002824 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2825 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002826 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2827 _Py_capitalize__doc__},
2828 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00002829 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__},
2830 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002831 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002832 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002833 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Ezio Melotti745d54d2013-11-16 19:10:57 +02002834 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002835 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002836 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2837 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2838 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002839 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002840 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2841 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002842 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2843 _Py_isalnum__doc__},
2844 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2845 _Py_isalpha__doc__},
2846 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2847 _Py_isdigit__doc__},
2848 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2849 _Py_islower__doc__},
2850 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2851 _Py_isspace__doc__},
2852 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2853 _Py_istitle__doc__},
2854 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2855 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002856 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002857 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2858 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002859 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2860 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002861 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002862 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2863 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2864 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2865 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2866 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2867 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2868 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002869 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002870 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002871 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002872 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002873 {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__},
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002874 {"splitlines", (PyCFunction)bytearray_splitlines,
2875 METH_VARARGS | METH_KEYWORDS, splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002876 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002877 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002878 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002879 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2880 _Py_swapcase__doc__},
2881 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002882 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002883 translate__doc__},
2884 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2885 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2886 {NULL}
2887};
2888
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002889PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002890"bytearray(iterable_of_ints) -> bytearray\n\
2891bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002892bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2893bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2894bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002895\n\
2896Construct an mutable bytearray object from:\n\
2897 - an iterable yielding integers in range(256)\n\
2898 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002899 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002900 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002901 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002902
2903
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002904static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002905
2906PyTypeObject PyByteArray_Type = {
2907 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2908 "bytearray",
2909 sizeof(PyByteArrayObject),
2910 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002911 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002912 0, /* tp_print */
2913 0, /* tp_getattr */
2914 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002915 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002916 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002917 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002918 &bytearray_as_sequence, /* tp_as_sequence */
2919 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002920 0, /* tp_hash */
2921 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002922 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002923 PyObject_GenericGetAttr, /* tp_getattro */
2924 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002925 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002926 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002927 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002928 0, /* tp_traverse */
2929 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002930 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002931 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002932 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002933 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002934 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002935 0, /* tp_members */
2936 0, /* tp_getset */
2937 0, /* tp_base */
2938 0, /* tp_dict */
2939 0, /* tp_descr_get */
2940 0, /* tp_descr_set */
2941 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002942 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002943 PyType_GenericAlloc, /* tp_alloc */
2944 PyType_GenericNew, /* tp_new */
2945 PyObject_Del, /* tp_free */
2946};
2947
2948/*********************** Bytes Iterator ****************************/
2949
2950typedef struct {
2951 PyObject_HEAD
2952 Py_ssize_t it_index;
2953 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2954} bytesiterobject;
2955
2956static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002957bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002958{
2959 _PyObject_GC_UNTRACK(it);
2960 Py_XDECREF(it->it_seq);
2961 PyObject_GC_Del(it);
2962}
2963
2964static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002965bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002966{
2967 Py_VISIT(it->it_seq);
2968 return 0;
2969}
2970
2971static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002972bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002973{
2974 PyByteArrayObject *seq;
2975 PyObject *item;
2976
2977 assert(it != NULL);
2978 seq = it->it_seq;
2979 if (seq == NULL)
2980 return NULL;
2981 assert(PyByteArray_Check(seq));
2982
2983 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2984 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002985 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002986 if (item != NULL)
2987 ++it->it_index;
2988 return item;
2989 }
2990
2991 Py_DECREF(seq);
2992 it->it_seq = NULL;
2993 return NULL;
2994}
2995
2996static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002997bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002998{
2999 Py_ssize_t len = 0;
3000 if (it->it_seq)
3001 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3002 return PyLong_FromSsize_t(len);
3003}
3004
3005PyDoc_STRVAR(length_hint_doc,
3006 "Private method returning an estimate of len(list(it)).");
3007
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003008static PyObject *
3009bytearrayiter_reduce(bytesiterobject *it)
3010{
3011 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02003012 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003013 it->it_seq, it->it_index);
3014 } else {
3015 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
3016 if (u == NULL)
3017 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02003018 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003019 }
3020}
3021
3022static PyObject *
3023bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3024{
3025 Py_ssize_t index = PyLong_AsSsize_t(state);
3026 if (index == -1 && PyErr_Occurred())
3027 return NULL;
3028 if (index < 0)
3029 index = 0;
3030 it->it_index = index;
3031 Py_RETURN_NONE;
3032}
3033
3034PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3035
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003036static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003037 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003038 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003039 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
3040 reduce_doc},
3041 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3042 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003043 {NULL, NULL} /* sentinel */
3044};
3045
3046PyTypeObject PyByteArrayIter_Type = {
3047 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3048 "bytearray_iterator", /* tp_name */
3049 sizeof(bytesiterobject), /* tp_basicsize */
3050 0, /* tp_itemsize */
3051 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003052 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003053 0, /* tp_print */
3054 0, /* tp_getattr */
3055 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003056 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003057 0, /* tp_repr */
3058 0, /* tp_as_number */
3059 0, /* tp_as_sequence */
3060 0, /* tp_as_mapping */
3061 0, /* tp_hash */
3062 0, /* tp_call */
3063 0, /* tp_str */
3064 PyObject_GenericGetAttr, /* tp_getattro */
3065 0, /* tp_setattro */
3066 0, /* tp_as_buffer */
3067 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3068 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003069 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003070 0, /* tp_clear */
3071 0, /* tp_richcompare */
3072 0, /* tp_weaklistoffset */
3073 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003074 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3075 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003076 0,
3077};
3078
3079static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003080bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003081{
3082 bytesiterobject *it;
3083
3084 if (!PyByteArray_Check(seq)) {
3085 PyErr_BadInternalCall();
3086 return NULL;
3087 }
3088 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3089 if (it == NULL)
3090 return NULL;
3091 it->it_index = 0;
3092 Py_INCREF(seq);
3093 it->it_seq = (PyByteArrayObject *)seq;
3094 _PyObject_GC_TRACK(it);
3095 return (PyObject *)it;
3096}