blob: 60b281179d9ba91ae86311eb67fcf01c30928bfd [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;
153 new->ob_exports = 0;
154
155 return (PyObject *)new;
156}
157
158Py_ssize_t
159PyByteArray_Size(PyObject *self)
160{
161 assert(self != NULL);
162 assert(PyByteArray_Check(self));
163
164 return PyByteArray_GET_SIZE(self);
165}
166
167char *
168PyByteArray_AsString(PyObject *self)
169{
170 assert(self != NULL);
171 assert(PyByteArray_Check(self));
172
173 return PyByteArray_AS_STRING(self);
174}
175
176int
177PyByteArray_Resize(PyObject *self, Py_ssize_t size)
178{
179 void *sval;
180 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
181
182 assert(self != NULL);
183 assert(PyByteArray_Check(self));
184 assert(size >= 0);
185
Antoine Pitrou5504e892008-12-06 21:27:53 +0000186 if (size == Py_SIZE(self)) {
187 return 0;
188 }
189 if (!_canresize((PyByteArrayObject *)self)) {
190 return -1;
191 }
192
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000193 if (size < alloc / 2) {
194 /* Major downsize; resize down to exact size */
195 alloc = size + 1;
196 }
197 else if (size < alloc) {
198 /* Within allocated size; quick exit */
199 Py_SIZE(self) = size;
200 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
201 return 0;
202 }
203 else if (size <= alloc * 1.125) {
204 /* Moderate upsize; overallocate similar to list_resize() */
205 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
206 }
207 else {
208 /* Major upsize; resize up to exact size */
209 alloc = size + 1;
210 }
211
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100212 sval = PyObject_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000213 if (sval == NULL) {
214 PyErr_NoMemory();
215 return -1;
216 }
217
218 ((PyByteArrayObject *)self)->ob_bytes = sval;
219 Py_SIZE(self) = size;
220 ((PyByteArrayObject *)self)->ob_alloc = alloc;
221 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
222
223 return 0;
224}
225
226PyObject *
227PyByteArray_Concat(PyObject *a, PyObject *b)
228{
229 Py_ssize_t size;
230 Py_buffer va, vb;
231 PyByteArrayObject *result = NULL;
232
233 va.len = -1;
234 vb.len = -1;
235 if (_getbuffer(a, &va) < 0 ||
236 _getbuffer(b, &vb) < 0) {
237 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
238 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
239 goto done;
240 }
241
242 size = va.len + vb.len;
243 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000244 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000245 goto done;
246 }
247
248 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
249 if (result != NULL) {
250 memcpy(result->ob_bytes, va.buf, va.len);
251 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
252 }
253
254 done:
255 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000256 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000257 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000258 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000259 return (PyObject *)result;
260}
261
262/* Functions stuffed into the type object */
263
264static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000265bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000266{
267 return Py_SIZE(self);
268}
269
270static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000271bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000272{
273 Py_ssize_t mysize;
274 Py_ssize_t size;
275 Py_buffer vo;
276
277 if (_getbuffer(other, &vo) < 0) {
278 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
279 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
280 return NULL;
281 }
282
283 mysize = Py_SIZE(self);
284 size = mysize + vo.len;
285 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000286 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000287 return PyErr_NoMemory();
288 }
289 if (size < self->ob_alloc) {
290 Py_SIZE(self) = size;
291 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
292 }
293 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000294 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000295 return NULL;
296 }
297 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000298 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000299 Py_INCREF(self);
300 return (PyObject *)self;
301}
302
303static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000304bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000305{
306 PyByteArrayObject *result;
307 Py_ssize_t mysize;
308 Py_ssize_t size;
309
310 if (count < 0)
311 count = 0;
312 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000313 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000314 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000315 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000316 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
317 if (result != NULL && size != 0) {
318 if (mysize == 1)
319 memset(result->ob_bytes, self->ob_bytes[0], size);
320 else {
321 Py_ssize_t i;
322 for (i = 0; i < count; i++)
323 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
324 }
325 }
326 return (PyObject *)result;
327}
328
329static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000330bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000331{
332 Py_ssize_t mysize;
333 Py_ssize_t size;
334
335 if (count < 0)
336 count = 0;
337 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000338 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000339 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000340 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000341 if (size < self->ob_alloc) {
342 Py_SIZE(self) = size;
343 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
344 }
345 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
346 return NULL;
347
348 if (mysize == 1)
349 memset(self->ob_bytes, self->ob_bytes[0], size);
350 else {
351 Py_ssize_t i;
352 for (i = 1; i < count; i++)
353 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
354 }
355
356 Py_INCREF(self);
357 return (PyObject *)self;
358}
359
360static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000361bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000362{
363 if (i < 0)
364 i += Py_SIZE(self);
365 if (i < 0 || i >= Py_SIZE(self)) {
366 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
367 return NULL;
368 }
369 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
370}
371
372static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000373bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000374{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000375 if (PyIndex_Check(index)) {
376 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000377
378 if (i == -1 && PyErr_Occurred())
379 return NULL;
380
381 if (i < 0)
382 i += PyByteArray_GET_SIZE(self);
383
384 if (i < 0 || i >= Py_SIZE(self)) {
385 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
386 return NULL;
387 }
388 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
389 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000390 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000391 Py_ssize_t start, stop, step, slicelength, cur, i;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000392 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000393 PyByteArray_GET_SIZE(self),
394 &start, &stop, &step, &slicelength) < 0) {
395 return NULL;
396 }
397
398 if (slicelength <= 0)
399 return PyByteArray_FromStringAndSize("", 0);
400 else if (step == 1) {
401 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
402 slicelength);
403 }
404 else {
405 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000406 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000407 PyObject *result;
408
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000409 result = PyByteArray_FromStringAndSize(NULL, slicelength);
410 if (result == NULL)
411 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000412
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000413 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000414 for (cur = start, i = 0; i < slicelength;
415 cur += step, i++) {
416 result_buf[i] = source_buf[cur];
417 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000418 return result;
419 }
420 }
421 else {
422 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
423 return NULL;
424 }
425}
426
427static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000428bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000429 PyObject *values)
430{
431 Py_ssize_t avail, needed;
432 void *bytes;
433 Py_buffer vbytes;
434 int res = 0;
435
436 vbytes.len = -1;
437 if (values == (PyObject *)self) {
438 /* Make a copy and call this function recursively */
439 int err;
440 values = PyByteArray_FromObject(values);
441 if (values == NULL)
442 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000443 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000444 Py_DECREF(values);
445 return err;
446 }
447 if (values == NULL) {
448 /* del b[lo:hi] */
449 bytes = NULL;
450 needed = 0;
451 }
452 else {
453 if (_getbuffer(values, &vbytes) < 0) {
454 PyErr_Format(PyExc_TypeError,
Georg Brandl3dbca812008-07-23 16:10:53 +0000455 "can't set bytearray slice from %.100s",
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000456 Py_TYPE(values)->tp_name);
457 return -1;
458 }
459 needed = vbytes.len;
460 bytes = vbytes.buf;
461 }
462
463 if (lo < 0)
464 lo = 0;
465 if (hi < lo)
466 hi = lo;
467 if (hi > Py_SIZE(self))
468 hi = Py_SIZE(self);
469
470 avail = hi - lo;
471 if (avail < 0)
472 lo = hi = avail = 0;
473
474 if (avail != needed) {
475 if (avail > needed) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000476 if (!_canresize(self)) {
477 res = -1;
478 goto finish;
479 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000480 /*
481 0 lo hi old_size
482 | |<----avail----->|<-----tomove------>|
483 | |<-needed->|<-----tomove------>|
484 0 lo new_hi new_size
485 */
486 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
487 Py_SIZE(self) - hi);
488 }
489 /* XXX(nnorwitz): need to verify this can't overflow! */
490 if (PyByteArray_Resize((PyObject *)self,
491 Py_SIZE(self) + needed - avail) < 0) {
492 res = -1;
493 goto finish;
494 }
495 if (avail < needed) {
496 /*
497 0 lo hi old_size
498 | |<-avail->|<-----tomove------>|
499 | |<----needed---->|<-----tomove------>|
500 0 lo new_hi new_size
501 */
502 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
503 Py_SIZE(self) - lo - needed);
504 }
505 }
506
507 if (needed > 0)
508 memcpy(self->ob_bytes + lo, bytes, needed);
509
510
511 finish:
512 if (vbytes.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000513 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000514 return res;
515}
516
517static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000518bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000519{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000520 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000521
522 if (i < 0)
523 i += Py_SIZE(self);
524
525 if (i < 0 || i >= Py_SIZE(self)) {
526 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
527 return -1;
528 }
529
530 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000531 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000532
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000533 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000534 return -1;
535
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000536 self->ob_bytes[i] = ival;
537 return 0;
538}
539
540static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000541bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000542{
543 Py_ssize_t start, stop, step, slicelen, needed;
544 char *bytes;
545
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000546 if (PyIndex_Check(index)) {
547 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000548
549 if (i == -1 && PyErr_Occurred())
550 return -1;
551
552 if (i < 0)
553 i += PyByteArray_GET_SIZE(self);
554
555 if (i < 0 || i >= Py_SIZE(self)) {
556 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
557 return -1;
558 }
559
560 if (values == NULL) {
561 /* Fall through to slice assignment */
562 start = i;
563 stop = i + 1;
564 step = 1;
565 slicelen = 1;
566 }
567 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000568 int ival;
569 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000570 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000571 self->ob_bytes[i] = (char)ival;
572 return 0;
573 }
574 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000575 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000576 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000577 PyByteArray_GET_SIZE(self),
578 &start, &stop, &step, &slicelen) < 0) {
579 return -1;
580 }
581 }
582 else {
583 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
584 return -1;
585 }
586
587 if (values == NULL) {
588 bytes = NULL;
589 needed = 0;
590 }
591 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100592 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200593 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
594 PyErr_SetString(PyExc_TypeError,
595 "can assign only bytes, buffers, or iterables "
596 "of ints in range(0, 256)");
597 return -1;
598 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000599 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000600 values = PyByteArray_FromObject(values);
601 if (values == NULL)
602 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000603 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000604 Py_DECREF(values);
605 return err;
606 }
607 else {
608 assert(PyByteArray_Check(values));
609 bytes = ((PyByteArrayObject *)values)->ob_bytes;
610 needed = Py_SIZE(values);
611 }
612 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
613 if ((step < 0 && start < stop) ||
614 (step > 0 && start > stop))
615 stop = start;
616 if (step == 1) {
617 if (slicelen != needed) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000618 if (!_canresize(self))
619 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000620 if (slicelen > needed) {
621 /*
622 0 start stop old_size
623 | |<---slicelen--->|<-----tomove------>|
624 | |<-needed->|<-----tomove------>|
625 0 lo new_hi new_size
626 */
627 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
628 Py_SIZE(self) - stop);
629 }
630 if (PyByteArray_Resize((PyObject *)self,
631 Py_SIZE(self) + needed - slicelen) < 0)
632 return -1;
633 if (slicelen < needed) {
634 /*
635 0 lo hi old_size
636 | |<-avail->|<-----tomove------>|
637 | |<----needed---->|<-----tomove------>|
638 0 lo new_hi new_size
639 */
640 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
641 Py_SIZE(self) - start - needed);
642 }
643 }
644
645 if (needed > 0)
646 memcpy(self->ob_bytes + start, bytes, needed);
647
648 return 0;
649 }
650 else {
651 if (needed == 0) {
652 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000653 size_t cur;
654 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000655
Antoine Pitrou5504e892008-12-06 21:27:53 +0000656 if (!_canresize(self))
657 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000658
659 if (slicelen == 0)
660 /* Nothing to do here. */
661 return 0;
662
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000663 if (step < 0) {
664 stop = start + 1;
665 start = stop + step * (slicelen - 1) - 1;
666 step = -step;
667 }
668 for (cur = start, i = 0;
669 i < slicelen; cur += step, i++) {
670 Py_ssize_t lim = step - 1;
671
Mark Dickinson66f575b2010-02-14 12:53:32 +0000672 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000673 lim = PyByteArray_GET_SIZE(self) - cur - 1;
674
675 memmove(self->ob_bytes + cur - i,
676 self->ob_bytes + cur + 1, lim);
677 }
678 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000679 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000680 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000681 memmove(self->ob_bytes + cur - slicelen,
682 self->ob_bytes + cur,
683 PyByteArray_GET_SIZE(self) - cur);
684 }
685 if (PyByteArray_Resize((PyObject *)self,
686 PyByteArray_GET_SIZE(self) - slicelen) < 0)
687 return -1;
688
689 return 0;
690 }
691 else {
692 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000693 Py_ssize_t i;
694 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000695
696 if (needed != slicelen) {
697 PyErr_Format(PyExc_ValueError,
698 "attempt to assign bytes of size %zd "
699 "to extended slice of size %zd",
700 needed, slicelen);
701 return -1;
702 }
703 for (cur = start, i = 0; i < slicelen; cur += step, i++)
704 self->ob_bytes[cur] = bytes[i];
705 return 0;
706 }
707 }
708}
709
710static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000711bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000712{
713 static char *kwlist[] = {"source", "encoding", "errors", 0};
714 PyObject *arg = NULL;
715 const char *encoding = NULL;
716 const char *errors = NULL;
717 Py_ssize_t count;
718 PyObject *it;
719 PyObject *(*iternext)(PyObject *);
720
721 if (Py_SIZE(self) != 0) {
722 /* Empty previous contents (yes, do this first of all!) */
723 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
724 return -1;
725 }
726
727 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000728 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000729 &arg, &encoding, &errors))
730 return -1;
731
732 /* Make a quick exit if no first argument */
733 if (arg == NULL) {
734 if (encoding != NULL || errors != NULL) {
735 PyErr_SetString(PyExc_TypeError,
736 "encoding or errors without sequence argument");
737 return -1;
738 }
739 return 0;
740 }
741
742 if (PyUnicode_Check(arg)) {
743 /* Encode via the codec registry */
744 PyObject *encoded, *new;
745 if (encoding == NULL) {
746 PyErr_SetString(PyExc_TypeError,
747 "string argument without an encoding");
748 return -1;
749 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000750 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000751 if (encoded == NULL)
752 return -1;
753 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000754 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000755 Py_DECREF(encoded);
756 if (new == NULL)
757 return -1;
758 Py_DECREF(new);
759 return 0;
760 }
761
762 /* If it's not unicode, there can't be encoding or errors */
763 if (encoding != NULL || errors != NULL) {
764 PyErr_SetString(PyExc_TypeError,
765 "encoding or errors without a string argument");
766 return -1;
767 }
768
769 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000770 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
771 if (count == -1 && PyErr_Occurred()) {
772 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000773 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000774 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000775 }
776 else if (count < 0) {
777 PyErr_SetString(PyExc_ValueError, "negative count");
778 return -1;
779 }
780 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000781 if (count > 0) {
782 if (PyByteArray_Resize((PyObject *)self, count))
783 return -1;
784 memset(self->ob_bytes, 0, count);
785 }
786 return 0;
787 }
788
789 /* Use the buffer API */
790 if (PyObject_CheckBuffer(arg)) {
791 Py_ssize_t size;
792 Py_buffer view;
793 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
794 return -1;
795 size = view.len;
796 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
797 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200798 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000799 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000800 return 0;
801 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000802 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000803 return -1;
804 }
805
806 /* XXX Optimize this if the arguments is a list, tuple */
807
808 /* Get the iterator */
809 it = PyObject_GetIter(arg);
810 if (it == NULL)
811 return -1;
812 iternext = *Py_TYPE(it)->tp_iternext;
813
814 /* Run the iterator to exhaustion */
815 for (;;) {
816 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000817 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000818
819 /* Get the next item */
820 item = iternext(it);
821 if (item == NULL) {
822 if (PyErr_Occurred()) {
823 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
824 goto error;
825 PyErr_Clear();
826 }
827 break;
828 }
829
830 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000831 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000832 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000833 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000834 goto error;
835
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000836 /* Append the byte */
837 if (Py_SIZE(self) < self->ob_alloc)
838 Py_SIZE(self)++;
839 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
840 goto error;
841 self->ob_bytes[Py_SIZE(self)-1] = value;
842 }
843
844 /* Clean up and return success */
845 Py_DECREF(it);
846 return 0;
847
848 error:
849 /* Error handling when it != NULL */
850 Py_DECREF(it);
851 return -1;
852}
853
854/* Mostly copied from string_repr, but without the
855 "smart quote" functionality. */
856static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000857bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000858{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000859 const char *quote_prefix = "bytearray(b";
860 const char *quote_postfix = ")";
861 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200862 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000863 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000864 PyObject *v;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200865 register Py_ssize_t i;
866 register char c;
867 register char *p;
868 int quote;
869 char *test, *start;
870 char *buffer;
871
872 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000873 PyErr_SetString(PyExc_OverflowError,
874 "bytearray object is too large to make repr");
875 return NULL;
876 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200877
878 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100879 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200880 if (buffer == NULL) {
881 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000882 return NULL;
883 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000884
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200885 /* Figure out which quote to use; single is preferred */
886 quote = '\'';
887 start = PyByteArray_AS_STRING(self);
888 for (test = start; test < start+length; ++test) {
889 if (*test == '"') {
890 quote = '\''; /* back to single */
891 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000892 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200893 else if (*test == '\'')
894 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000895 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200896
897 p = buffer;
898 while (*quote_prefix)
899 *p++ = *quote_prefix++;
900 *p++ = quote;
901
902 for (i = 0; i < length; i++) {
903 /* There's at least enough room for a hex escape
904 and a closing quote. */
905 assert(newsize - (p - buffer) >= 5);
906 c = self->ob_bytes[i];
907 if (c == '\'' || c == '\\')
908 *p++ = '\\', *p++ = c;
909 else if (c == '\t')
910 *p++ = '\\', *p++ = 't';
911 else if (c == '\n')
912 *p++ = '\\', *p++ = 'n';
913 else if (c == '\r')
914 *p++ = '\\', *p++ = 'r';
915 else if (c == 0)
916 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
917 else if (c < ' ' || c >= 0x7f) {
918 *p++ = '\\';
919 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200920 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
921 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200922 }
923 else
924 *p++ = c;
925 }
926 assert(newsize - (p - buffer) >= 1);
927 *p++ = quote;
928 while (*quote_postfix) {
929 *p++ = *quote_postfix++;
930 }
931
932 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100933 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200934 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000935}
936
937static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000938bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000939{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000940 if (Py_BytesWarningFlag) {
941 if (PyErr_WarnEx(PyExc_BytesWarning,
942 "str() on a bytearray instance", 1))
943 return NULL;
944 }
945 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000946}
947
948static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000949bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000950{
951 Py_ssize_t self_size, other_size;
952 Py_buffer self_bytes, other_bytes;
953 PyObject *res;
954 Py_ssize_t minsize;
955 int cmp;
956
957 /* Bytes can be compared to anything that supports the (binary)
958 buffer API. Except that a comparison with Unicode is always an
959 error, even if the comparison is for equality. */
960 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
961 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000962 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000963 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000964 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000965 return NULL;
966 }
967
Brian Curtindfc80e32011-08-10 20:28:54 -0500968 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000969 }
970
971 self_size = _getbuffer(self, &self_bytes);
972 if (self_size < 0) {
973 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -0500974 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000975 }
976
977 other_size = _getbuffer(other, &other_bytes);
978 if (other_size < 0) {
979 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +0000980 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -0500981 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000982 }
983
984 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
985 /* Shortcut: if the lengths differ, the objects differ */
986 cmp = (op == Py_NE);
987 }
988 else {
989 minsize = self_size;
990 if (other_size < minsize)
991 minsize = other_size;
992
993 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
994 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
995
996 if (cmp == 0) {
997 if (self_size < other_size)
998 cmp = -1;
999 else if (self_size > other_size)
1000 cmp = 1;
1001 }
1002
1003 switch (op) {
1004 case Py_LT: cmp = cmp < 0; break;
1005 case Py_LE: cmp = cmp <= 0; break;
1006 case Py_EQ: cmp = cmp == 0; break;
1007 case Py_NE: cmp = cmp != 0; break;
1008 case Py_GT: cmp = cmp > 0; break;
1009 case Py_GE: cmp = cmp >= 0; break;
1010 }
1011 }
1012
1013 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001014 PyBuffer_Release(&self_bytes);
1015 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001016 Py_INCREF(res);
1017 return res;
1018}
1019
1020static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001021bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001022{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001023 if (self->ob_exports > 0) {
1024 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001025 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001026 PyErr_Print();
1027 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001028 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001029 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001030 }
1031 Py_TYPE(self)->tp_free((PyObject *)self);
1032}
1033
1034
1035/* -------------------------------------------------------------------- */
1036/* Methods */
1037
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001038#define FASTSEARCH fastsearch
1039#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001040#define STRINGLIB_CHAR char
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001041#define STRINGLIB_LEN PyByteArray_GET_SIZE
1042#define STRINGLIB_STR PyByteArray_AS_STRING
1043#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001044#define STRINGLIB_ISSPACE Py_ISSPACE
1045#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001046#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1047#define STRINGLIB_MUTABLE 1
1048
1049#include "stringlib/fastsearch.h"
1050#include "stringlib/count.h"
1051#include "stringlib/find.h"
1052#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001053#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001054#include "stringlib/ctype.h"
1055#include "stringlib/transmogrify.h"
1056
1057
1058/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1059were copied from the old char* style string object. */
1060
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001061/* helper macro to fixup start/end slice values */
1062#define ADJUST_INDICES(start, end, len) \
1063 if (end > len) \
1064 end = len; \
1065 else if (end < 0) { \
1066 end += len; \
1067 if (end < 0) \
1068 end = 0; \
1069 } \
1070 if (start < 0) { \
1071 start += len; \
1072 if (start < 0) \
1073 start = 0; \
1074 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001075
1076Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001077bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001078{
1079 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001080 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001081 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001082 const char *sub;
1083 Py_ssize_t sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001084 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1085 Py_ssize_t res;
1086
Antoine Pitrouac65d962011-10-20 23:54:17 +02001087 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1088 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001089 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001090
1091 if (subobj) {
1092 if (_getbuffer(subobj, &subbuf) < 0)
1093 return -2;
1094
1095 sub = subbuf.buf;
1096 sub_len = subbuf.len;
1097 }
1098 else {
1099 sub = &byte;
1100 sub_len = 1;
1101 }
1102
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001103 if (dir > 0)
1104 res = stringlib_find_slice(
1105 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001106 sub, sub_len, start, end);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001107 else
1108 res = stringlib_rfind_slice(
1109 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001110 sub, sub_len, start, end);
1111
1112 if (subobj)
1113 PyBuffer_Release(&subbuf);
1114
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001115 return res;
1116}
1117
1118PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001119"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001120\n\
1121Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001122such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001123arguments start and end are interpreted as in slice notation.\n\
1124\n\
1125Return -1 on failure.");
1126
1127static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001128bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001129{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001130 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001131 if (result == -2)
1132 return NULL;
1133 return PyLong_FromSsize_t(result);
1134}
1135
1136PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001137"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001138\n\
1139Return the number of non-overlapping occurrences of subsection sub in\n\
1140bytes B[start:end]. Optional arguments start and end are interpreted\n\
1141as in slice notation.");
1142
1143static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001144bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001145{
1146 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001147 const char *str = PyByteArray_AS_STRING(self), *sub;
1148 Py_ssize_t sub_len;
1149 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001150 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001151
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001152 Py_buffer vsub;
1153 PyObject *count_obj;
1154
Antoine Pitrouac65d962011-10-20 23:54:17 +02001155 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1156 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001157 return NULL;
1158
Antoine Pitrouac65d962011-10-20 23:54:17 +02001159 if (sub_obj) {
1160 if (_getbuffer(sub_obj, &vsub) < 0)
1161 return NULL;
1162
1163 sub = vsub.buf;
1164 sub_len = vsub.len;
1165 }
1166 else {
1167 sub = &byte;
1168 sub_len = 1;
1169 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001170
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001171 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001172
1173 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001174 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001175 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001176
1177 if (sub_obj)
1178 PyBuffer_Release(&vsub);
1179
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001180 return count_obj;
1181}
1182
Eli Bendersky4db28d32011-03-03 18:21:02 +00001183PyDoc_STRVAR(clear__doc__,
1184"B.clear() -> None\n\
1185\n\
1186Remove all items from B.");
1187
Victor Stinner6430fd52011-09-29 04:02:13 +02001188static PyObject *
Eli Bendersky4db28d32011-03-03 18:21:02 +00001189bytearray_clear(PyByteArrayObject *self)
1190{
1191 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1192 return NULL;
1193 Py_RETURN_NONE;
1194}
1195
1196PyDoc_STRVAR(copy__doc__,
1197"B.copy() -> bytearray\n\
1198\n\
1199Return a copy of B.");
1200
1201static PyObject *
1202bytearray_copy(PyByteArrayObject *self)
1203{
1204 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1205 PyByteArray_GET_SIZE(self));
1206}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001207
1208PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001209"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001210\n\
1211Like B.find() but raise ValueError when the subsection is not found.");
1212
1213static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001214bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001215{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001216 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001217 if (result == -2)
1218 return NULL;
1219 if (result == -1) {
1220 PyErr_SetString(PyExc_ValueError,
1221 "subsection not found");
1222 return NULL;
1223 }
1224 return PyLong_FromSsize_t(result);
1225}
1226
1227
1228PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001229"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001230\n\
1231Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001232such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001233arguments start and end are interpreted as in slice notation.\n\
1234\n\
1235Return -1 on failure.");
1236
1237static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001238bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001239{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001240 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001241 if (result == -2)
1242 return NULL;
1243 return PyLong_FromSsize_t(result);
1244}
1245
1246
1247PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001248"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001249\n\
1250Like B.rfind() but raise ValueError when the subsection is not found.");
1251
1252static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001253bytearray_rindex(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
1267static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001268bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001269{
1270 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1271 if (ival == -1 && PyErr_Occurred()) {
1272 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001273 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001274 PyErr_Clear();
1275 if (_getbuffer(arg, &varg) < 0)
1276 return -1;
1277 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1278 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001279 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001280 return pos >= 0;
1281 }
1282 if (ival < 0 || ival >= 256) {
1283 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1284 return -1;
1285 }
1286
Antoine Pitrou0010d372010-08-15 17:12:55 +00001287 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001288}
1289
1290
1291/* Matches the end (direction >= 0) or start (direction < 0) of self
1292 * against substr, using the start and end arguments. Returns
1293 * -1 on error, 0 if not found and 1 if found.
1294 */
1295Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001296_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001297 Py_ssize_t end, int direction)
1298{
1299 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1300 const char* str;
1301 Py_buffer vsubstr;
1302 int rv = 0;
1303
1304 str = PyByteArray_AS_STRING(self);
1305
1306 if (_getbuffer(substr, &vsubstr) < 0)
1307 return -1;
1308
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001309 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001310
1311 if (direction < 0) {
1312 /* startswith */
1313 if (start+vsubstr.len > len) {
1314 goto done;
1315 }
1316 } else {
1317 /* endswith */
1318 if (end-start < vsubstr.len || start > len) {
1319 goto done;
1320 }
1321
1322 if (end-vsubstr.len > start)
1323 start = end - vsubstr.len;
1324 }
1325 if (end-start >= vsubstr.len)
1326 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1327
1328done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001329 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001330 return rv;
1331}
1332
1333
1334PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001335"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001336\n\
1337Return True if B starts with the specified prefix, False otherwise.\n\
1338With optional start, test B beginning at that position.\n\
1339With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001340prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001341
1342static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001343bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001344{
1345 Py_ssize_t start = 0;
1346 Py_ssize_t end = PY_SSIZE_T_MAX;
1347 PyObject *subobj;
1348 int result;
1349
Jesus Ceaac451502011-04-20 17:09:23 +02001350 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001351 return NULL;
1352 if (PyTuple_Check(subobj)) {
1353 Py_ssize_t i;
1354 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001355 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001356 PyTuple_GET_ITEM(subobj, i),
1357 start, end, -1);
1358 if (result == -1)
1359 return NULL;
1360 else if (result) {
1361 Py_RETURN_TRUE;
1362 }
1363 }
1364 Py_RETURN_FALSE;
1365 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001366 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001367 if (result == -1) {
1368 if (PyErr_ExceptionMatches(PyExc_TypeError))
1369 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1370 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001371 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001372 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001373 else
1374 return PyBool_FromLong(result);
1375}
1376
1377PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001378"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001379\n\
1380Return True if B ends with the specified suffix, False otherwise.\n\
1381With optional start, test B beginning at that position.\n\
1382With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001383suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001384
1385static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001386bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001387{
1388 Py_ssize_t start = 0;
1389 Py_ssize_t end = PY_SSIZE_T_MAX;
1390 PyObject *subobj;
1391 int result;
1392
Jesus Ceaac451502011-04-20 17:09:23 +02001393 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001394 return NULL;
1395 if (PyTuple_Check(subobj)) {
1396 Py_ssize_t i;
1397 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001398 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001399 PyTuple_GET_ITEM(subobj, i),
1400 start, end, +1);
1401 if (result == -1)
1402 return NULL;
1403 else if (result) {
1404 Py_RETURN_TRUE;
1405 }
1406 }
1407 Py_RETURN_FALSE;
1408 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001409 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001410 if (result == -1) {
1411 if (PyErr_ExceptionMatches(PyExc_TypeError))
1412 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1413 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001414 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001415 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001416 else
1417 return PyBool_FromLong(result);
1418}
1419
1420
1421PyDoc_STRVAR(translate__doc__,
1422"B.translate(table[, deletechars]) -> bytearray\n\
1423\n\
1424Return a copy of B, where all characters occurring in the\n\
1425optional argument deletechars are removed, and the remaining\n\
1426characters have been mapped through the given translation\n\
1427table, which must be a bytes object of length 256.");
1428
1429static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001430bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001431{
1432 register char *input, *output;
1433 register const char *table;
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001434 register Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001435 PyObject *input_obj = (PyObject*)self;
1436 const char *output_start;
1437 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001438 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001439 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001440 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001441 Py_buffer vtable, vdel;
1442
1443 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1444 &tableobj, &delobj))
1445 return NULL;
1446
Georg Brandlccc47b62008-12-28 11:44:14 +00001447 if (tableobj == Py_None) {
1448 table = NULL;
1449 tableobj = NULL;
1450 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001451 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001452 } else {
1453 if (vtable.len != 256) {
1454 PyErr_SetString(PyExc_ValueError,
1455 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001456 PyBuffer_Release(&vtable);
1457 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001458 }
1459 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001460 }
1461
1462 if (delobj != NULL) {
1463 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001464 if (tableobj != NULL)
1465 PyBuffer_Release(&vtable);
1466 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001467 }
1468 }
1469 else {
1470 vdel.buf = NULL;
1471 vdel.len = 0;
1472 }
1473
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001474 inlen = PyByteArray_GET_SIZE(input_obj);
1475 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1476 if (result == NULL)
1477 goto done;
1478 output_start = output = PyByteArray_AsString(result);
1479 input = PyByteArray_AS_STRING(input_obj);
1480
Georg Brandlccc47b62008-12-28 11:44:14 +00001481 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001482 /* If no deletions are required, use faster code */
1483 for (i = inlen; --i >= 0; ) {
1484 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001485 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001486 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001487 goto done;
1488 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001489
1490 if (table == NULL) {
1491 for (i = 0; i < 256; i++)
1492 trans_table[i] = Py_CHARMASK(i);
1493 } else {
1494 for (i = 0; i < 256; i++)
1495 trans_table[i] = Py_CHARMASK(table[i]);
1496 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001497
1498 for (i = 0; i < vdel.len; i++)
1499 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1500
1501 for (i = inlen; --i >= 0; ) {
1502 c = Py_CHARMASK(*input++);
1503 if (trans_table[c] != -1)
1504 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1505 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001506 }
1507 /* Fix the size of the resulting string */
1508 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001509 if (PyByteArray_Resize(result, output - output_start) < 0) {
1510 Py_CLEAR(result);
1511 goto done;
1512 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001513
1514done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001515 if (tableobj != NULL)
1516 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001517 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001518 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001519 return result;
1520}
1521
1522
Georg Brandlabc38772009-04-12 15:51:51 +00001523static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001524bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001525{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001526 return _Py_bytes_maketrans(args);
Georg Brandlabc38772009-04-12 15:51:51 +00001527}
1528
1529
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001530/* find and count characters and substrings */
1531
1532#define findchar(target, target_len, c) \
1533 ((char *)memchr((const void *)(target), c, target_len))
1534
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001535
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001536/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001537Py_LOCAL(PyByteArrayObject *)
1538return_self(PyByteArrayObject *self)
1539{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001540 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001541 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1542 PyByteArray_AS_STRING(self),
1543 PyByteArray_GET_SIZE(self));
1544}
1545
1546Py_LOCAL_INLINE(Py_ssize_t)
1547countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1548{
1549 Py_ssize_t count=0;
1550 const char *start=target;
1551 const char *end=target+target_len;
1552
1553 while ( (start=findchar(start, end-start, c)) != NULL ) {
1554 count++;
1555 if (count >= maxcount)
1556 break;
1557 start += 1;
1558 }
1559 return count;
1560}
1561
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001562
1563/* Algorithms for different cases of string replacement */
1564
1565/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1566Py_LOCAL(PyByteArrayObject *)
1567replace_interleave(PyByteArrayObject *self,
1568 const char *to_s, Py_ssize_t to_len,
1569 Py_ssize_t maxcount)
1570{
1571 char *self_s, *result_s;
1572 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001573 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001574 PyByteArrayObject *result;
1575
1576 self_len = PyByteArray_GET_SIZE(self);
1577
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001578 /* 1 at the end plus 1 after every character;
1579 count = min(maxcount, self_len + 1) */
1580 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001581 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001582 else
1583 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1584 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001585
1586 /* Check for overflow */
1587 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001588 assert(count > 0);
1589 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001590 PyErr_SetString(PyExc_OverflowError,
1591 "replace string is too long");
1592 return NULL;
1593 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001594 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001595
1596 if (! (result = (PyByteArrayObject *)
1597 PyByteArray_FromStringAndSize(NULL, result_len)) )
1598 return NULL;
1599
1600 self_s = PyByteArray_AS_STRING(self);
1601 result_s = PyByteArray_AS_STRING(result);
1602
1603 /* TODO: special case single character, which doesn't need memcpy */
1604
1605 /* Lay the first one down (guaranteed this will occur) */
1606 Py_MEMCPY(result_s, to_s, to_len);
1607 result_s += to_len;
1608 count -= 1;
1609
1610 for (i=0; i<count; i++) {
1611 *result_s++ = *self_s++;
1612 Py_MEMCPY(result_s, to_s, to_len);
1613 result_s += to_len;
1614 }
1615
1616 /* Copy the rest of the original string */
1617 Py_MEMCPY(result_s, self_s, self_len-i);
1618
1619 return result;
1620}
1621
1622/* Special case for deleting a single character */
1623/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1624Py_LOCAL(PyByteArrayObject *)
1625replace_delete_single_character(PyByteArrayObject *self,
1626 char from_c, Py_ssize_t maxcount)
1627{
1628 char *self_s, *result_s;
1629 char *start, *next, *end;
1630 Py_ssize_t self_len, result_len;
1631 Py_ssize_t count;
1632 PyByteArrayObject *result;
1633
1634 self_len = PyByteArray_GET_SIZE(self);
1635 self_s = PyByteArray_AS_STRING(self);
1636
1637 count = countchar(self_s, self_len, from_c, maxcount);
1638 if (count == 0) {
1639 return return_self(self);
1640 }
1641
1642 result_len = self_len - count; /* from_len == 1 */
1643 assert(result_len>=0);
1644
1645 if ( (result = (PyByteArrayObject *)
1646 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1647 return NULL;
1648 result_s = PyByteArray_AS_STRING(result);
1649
1650 start = self_s;
1651 end = self_s + self_len;
1652 while (count-- > 0) {
1653 next = findchar(start, end-start, from_c);
1654 if (next == NULL)
1655 break;
1656 Py_MEMCPY(result_s, start, next-start);
1657 result_s += (next-start);
1658 start = next+1;
1659 }
1660 Py_MEMCPY(result_s, start, end-start);
1661
1662 return result;
1663}
1664
1665/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1666
1667Py_LOCAL(PyByteArrayObject *)
1668replace_delete_substring(PyByteArrayObject *self,
1669 const char *from_s, Py_ssize_t from_len,
1670 Py_ssize_t maxcount)
1671{
1672 char *self_s, *result_s;
1673 char *start, *next, *end;
1674 Py_ssize_t self_len, result_len;
1675 Py_ssize_t count, offset;
1676 PyByteArrayObject *result;
1677
1678 self_len = PyByteArray_GET_SIZE(self);
1679 self_s = PyByteArray_AS_STRING(self);
1680
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001681 count = stringlib_count(self_s, self_len,
1682 from_s, from_len,
1683 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001684
1685 if (count == 0) {
1686 /* no matches */
1687 return return_self(self);
1688 }
1689
1690 result_len = self_len - (count * from_len);
1691 assert (result_len>=0);
1692
1693 if ( (result = (PyByteArrayObject *)
1694 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1695 return NULL;
1696
1697 result_s = PyByteArray_AS_STRING(result);
1698
1699 start = self_s;
1700 end = self_s + self_len;
1701 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001702 offset = stringlib_find(start, end-start,
1703 from_s, from_len,
1704 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001705 if (offset == -1)
1706 break;
1707 next = start + offset;
1708
1709 Py_MEMCPY(result_s, start, next-start);
1710
1711 result_s += (next-start);
1712 start = next+from_len;
1713 }
1714 Py_MEMCPY(result_s, start, end-start);
1715 return result;
1716}
1717
1718/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1719Py_LOCAL(PyByteArrayObject *)
1720replace_single_character_in_place(PyByteArrayObject *self,
1721 char from_c, char to_c,
1722 Py_ssize_t maxcount)
1723{
Antoine Pitroud1188562010-06-09 16:38:55 +00001724 char *self_s, *result_s, *start, *end, *next;
1725 Py_ssize_t self_len;
1726 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001727
Antoine Pitroud1188562010-06-09 16:38:55 +00001728 /* The result string will be the same size */
1729 self_s = PyByteArray_AS_STRING(self);
1730 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001731
Antoine Pitroud1188562010-06-09 16:38:55 +00001732 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001733
Antoine Pitroud1188562010-06-09 16:38:55 +00001734 if (next == NULL) {
1735 /* No matches; return the original bytes */
1736 return return_self(self);
1737 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001738
Antoine Pitroud1188562010-06-09 16:38:55 +00001739 /* Need to make a new bytes */
1740 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1741 if (result == NULL)
1742 return NULL;
1743 result_s = PyByteArray_AS_STRING(result);
1744 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001745
Antoine Pitroud1188562010-06-09 16:38:55 +00001746 /* change everything in-place, starting with this one */
1747 start = result_s + (next-self_s);
1748 *start = to_c;
1749 start++;
1750 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001751
Antoine Pitroud1188562010-06-09 16:38:55 +00001752 while (--maxcount > 0) {
1753 next = findchar(start, end-start, from_c);
1754 if (next == NULL)
1755 break;
1756 *next = to_c;
1757 start = next+1;
1758 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001759
Antoine Pitroud1188562010-06-09 16:38:55 +00001760 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001761}
1762
1763/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1764Py_LOCAL(PyByteArrayObject *)
1765replace_substring_in_place(PyByteArrayObject *self,
1766 const char *from_s, Py_ssize_t from_len,
1767 const char *to_s, Py_ssize_t to_len,
1768 Py_ssize_t maxcount)
1769{
1770 char *result_s, *start, *end;
1771 char *self_s;
1772 Py_ssize_t self_len, offset;
1773 PyByteArrayObject *result;
1774
1775 /* The result bytes will be the same size */
1776
1777 self_s = PyByteArray_AS_STRING(self);
1778 self_len = PyByteArray_GET_SIZE(self);
1779
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001780 offset = stringlib_find(self_s, self_len,
1781 from_s, from_len,
1782 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001783 if (offset == -1) {
1784 /* No matches; return the original bytes */
1785 return return_self(self);
1786 }
1787
1788 /* Need to make a new bytes */
1789 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1790 if (result == NULL)
1791 return NULL;
1792 result_s = PyByteArray_AS_STRING(result);
1793 Py_MEMCPY(result_s, self_s, self_len);
1794
1795 /* change everything in-place, starting with this one */
1796 start = result_s + offset;
1797 Py_MEMCPY(start, to_s, from_len);
1798 start += from_len;
1799 end = result_s + self_len;
1800
1801 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001802 offset = stringlib_find(start, end-start,
1803 from_s, from_len,
1804 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001805 if (offset==-1)
1806 break;
1807 Py_MEMCPY(start+offset, to_s, from_len);
1808 start += offset+from_len;
1809 }
1810
1811 return result;
1812}
1813
1814/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1815Py_LOCAL(PyByteArrayObject *)
1816replace_single_character(PyByteArrayObject *self,
1817 char from_c,
1818 const char *to_s, Py_ssize_t to_len,
1819 Py_ssize_t maxcount)
1820{
1821 char *self_s, *result_s;
1822 char *start, *next, *end;
1823 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001824 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001825 PyByteArrayObject *result;
1826
1827 self_s = PyByteArray_AS_STRING(self);
1828 self_len = PyByteArray_GET_SIZE(self);
1829
1830 count = countchar(self_s, self_len, from_c, maxcount);
1831 if (count == 0) {
1832 /* no matches, return unchanged */
1833 return return_self(self);
1834 }
1835
1836 /* use the difference between current and new, hence the "-1" */
1837 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001838 assert(count > 0);
1839 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001840 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1841 return NULL;
1842 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001843 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001844
1845 if ( (result = (PyByteArrayObject *)
1846 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1847 return NULL;
1848 result_s = PyByteArray_AS_STRING(result);
1849
1850 start = self_s;
1851 end = self_s + self_len;
1852 while (count-- > 0) {
1853 next = findchar(start, end-start, from_c);
1854 if (next == NULL)
1855 break;
1856
1857 if (next == start) {
1858 /* replace with the 'to' */
1859 Py_MEMCPY(result_s, to_s, to_len);
1860 result_s += to_len;
1861 start += 1;
1862 } else {
1863 /* copy the unchanged old then the 'to' */
1864 Py_MEMCPY(result_s, start, next-start);
1865 result_s += (next-start);
1866 Py_MEMCPY(result_s, to_s, to_len);
1867 result_s += to_len;
1868 start = next+1;
1869 }
1870 }
1871 /* Copy the remainder of the remaining bytes */
1872 Py_MEMCPY(result_s, start, end-start);
1873
1874 return result;
1875}
1876
1877/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1878Py_LOCAL(PyByteArrayObject *)
1879replace_substring(PyByteArrayObject *self,
1880 const char *from_s, Py_ssize_t from_len,
1881 const char *to_s, Py_ssize_t to_len,
1882 Py_ssize_t maxcount)
1883{
1884 char *self_s, *result_s;
1885 char *start, *next, *end;
1886 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001887 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001888 PyByteArrayObject *result;
1889
1890 self_s = PyByteArray_AS_STRING(self);
1891 self_len = PyByteArray_GET_SIZE(self);
1892
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001893 count = stringlib_count(self_s, self_len,
1894 from_s, from_len,
1895 maxcount);
1896
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001897 if (count == 0) {
1898 /* no matches, return unchanged */
1899 return return_self(self);
1900 }
1901
1902 /* Check for overflow */
1903 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001904 assert(count > 0);
1905 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001906 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1907 return NULL;
1908 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001909 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001910
1911 if ( (result = (PyByteArrayObject *)
1912 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1913 return NULL;
1914 result_s = PyByteArray_AS_STRING(result);
1915
1916 start = self_s;
1917 end = self_s + self_len;
1918 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001919 offset = stringlib_find(start, end-start,
1920 from_s, from_len,
1921 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001922 if (offset == -1)
1923 break;
1924 next = start+offset;
1925 if (next == start) {
1926 /* replace with the 'to' */
1927 Py_MEMCPY(result_s, to_s, to_len);
1928 result_s += to_len;
1929 start += from_len;
1930 } else {
1931 /* copy the unchanged old then the 'to' */
1932 Py_MEMCPY(result_s, start, next-start);
1933 result_s += (next-start);
1934 Py_MEMCPY(result_s, to_s, to_len);
1935 result_s += to_len;
1936 start = next+from_len;
1937 }
1938 }
1939 /* Copy the remainder of the remaining bytes */
1940 Py_MEMCPY(result_s, start, end-start);
1941
1942 return result;
1943}
1944
1945
1946Py_LOCAL(PyByteArrayObject *)
1947replace(PyByteArrayObject *self,
1948 const char *from_s, Py_ssize_t from_len,
1949 const char *to_s, Py_ssize_t to_len,
1950 Py_ssize_t maxcount)
1951{
1952 if (maxcount < 0) {
1953 maxcount = PY_SSIZE_T_MAX;
1954 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1955 /* nothing to do; return the original bytes */
1956 return return_self(self);
1957 }
1958
1959 if (maxcount == 0 ||
1960 (from_len == 0 && to_len == 0)) {
1961 /* nothing to do; return the original bytes */
1962 return return_self(self);
1963 }
1964
1965 /* Handle zero-length special cases */
1966
1967 if (from_len == 0) {
1968 /* insert the 'to' bytes everywhere. */
1969 /* >>> "Python".replace("", ".") */
1970 /* '.P.y.t.h.o.n.' */
1971 return replace_interleave(self, to_s, to_len, maxcount);
1972 }
1973
1974 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1975 /* point for an empty self bytes to generate a non-empty bytes */
1976 /* Special case so the remaining code always gets a non-empty bytes */
1977 if (PyByteArray_GET_SIZE(self) == 0) {
1978 return return_self(self);
1979 }
1980
1981 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00001982 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001983 if (from_len == 1) {
1984 return replace_delete_single_character(
1985 self, from_s[0], maxcount);
1986 } else {
1987 return replace_delete_substring(self, from_s, from_len, maxcount);
1988 }
1989 }
1990
1991 /* Handle special case where both bytes have the same length */
1992
1993 if (from_len == to_len) {
1994 if (from_len == 1) {
1995 return replace_single_character_in_place(
1996 self,
1997 from_s[0],
1998 to_s[0],
1999 maxcount);
2000 } else {
2001 return replace_substring_in_place(
2002 self, from_s, from_len, to_s, to_len, maxcount);
2003 }
2004 }
2005
2006 /* Otherwise use the more generic algorithms */
2007 if (from_len == 1) {
2008 return replace_single_character(self, from_s[0],
2009 to_s, to_len, maxcount);
2010 } else {
2011 /* len('from')>=2, len('to')>=1 */
2012 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2013 }
2014}
2015
2016
2017PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002018"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002019\n\
2020Return a copy of B with all occurrences of subsection\n\
2021old replaced by new. If the optional argument count is\n\
2022given, only the first count occurrences are replaced.");
2023
2024static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002025bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002026{
2027 Py_ssize_t count = -1;
2028 PyObject *from, *to, *res;
2029 Py_buffer vfrom, vto;
2030
2031 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2032 return NULL;
2033
2034 if (_getbuffer(from, &vfrom) < 0)
2035 return NULL;
2036 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +00002037 PyBuffer_Release(&vfrom);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002038 return NULL;
2039 }
2040
2041 res = (PyObject *)replace((PyByteArrayObject *) self,
2042 vfrom.buf, vfrom.len,
2043 vto.buf, vto.len, count);
2044
Martin v. Löwis423be952008-08-13 15:53:07 +00002045 PyBuffer_Release(&vfrom);
2046 PyBuffer_Release(&vto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002047 return res;
2048}
2049
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002050PyDoc_STRVAR(split__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002051"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002052\n\
2053Return a list of the sections in B, using sep as the delimiter.\n\
2054If sep is not given, B is split on ASCII whitespace characters\n\
2055(space, tab, return, newline, formfeed, vertical tab).\n\
2056If maxsplit is given, at most maxsplit splits are done.");
2057
2058static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002059bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002060{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002061 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002062 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2063 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002064 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002065 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002066 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002067
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002068 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
2069 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002070 return NULL;
2071 if (maxsplit < 0)
2072 maxsplit = PY_SSIZE_T_MAX;
2073
2074 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002075 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002076
2077 if (_getbuffer(subobj, &vsub) < 0)
2078 return NULL;
2079 sub = vsub.buf;
2080 n = vsub.len;
2081
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002082 list = stringlib_split(
2083 (PyObject*) self, s, len, sub, n, maxsplit
2084 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002085 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002086 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002087}
2088
2089PyDoc_STRVAR(partition__doc__,
2090"B.partition(sep) -> (head, sep, tail)\n\
2091\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002092Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002093the separator itself, and the part after it. If the separator is not\n\
2094found, returns B and two empty bytearray objects.");
2095
2096static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002097bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002098{
2099 PyObject *bytesep, *result;
2100
2101 bytesep = PyByteArray_FromObject(sep_obj);
2102 if (! bytesep)
2103 return NULL;
2104
2105 result = stringlib_partition(
2106 (PyObject*) self,
2107 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2108 bytesep,
2109 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2110 );
2111
2112 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002113 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002114}
2115
2116PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002117"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002118\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002119Search for the separator sep in B, starting at the end of B,\n\
2120and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002121part after it. If the separator is not found, returns two empty\n\
2122bytearray objects and B.");
2123
2124static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002125bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002126{
2127 PyObject *bytesep, *result;
2128
2129 bytesep = PyByteArray_FromObject(sep_obj);
2130 if (! bytesep)
2131 return NULL;
2132
2133 result = stringlib_rpartition(
2134 (PyObject*) self,
2135 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2136 bytesep,
2137 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2138 );
2139
2140 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002141 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002142}
2143
2144PyDoc_STRVAR(rsplit__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002145"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002146\n\
2147Return a list of the sections in B, using sep as the delimiter,\n\
2148starting at the end of B and working to the front.\n\
2149If sep is not given, B is split on ASCII whitespace characters\n\
2150(space, tab, return, newline, formfeed, vertical tab).\n\
2151If maxsplit is given, at most maxsplit splits are done.");
2152
2153static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002154bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002155{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002156 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002157 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2158 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002159 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002160 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002161 Py_buffer vsub;
2162
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002163 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit",
2164 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002165 return NULL;
2166 if (maxsplit < 0)
2167 maxsplit = PY_SSIZE_T_MAX;
2168
2169 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002170 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002171
2172 if (_getbuffer(subobj, &vsub) < 0)
2173 return NULL;
2174 sub = vsub.buf;
2175 n = vsub.len;
2176
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002177 list = stringlib_rsplit(
2178 (PyObject*) self, s, len, sub, n, maxsplit
2179 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002180 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002181 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002182}
2183
2184PyDoc_STRVAR(reverse__doc__,
2185"B.reverse() -> None\n\
2186\n\
2187Reverse the order of the values in B in place.");
2188static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002189bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002190{
2191 char swap, *head, *tail;
2192 Py_ssize_t i, j, n = Py_SIZE(self);
2193
2194 j = n / 2;
2195 head = self->ob_bytes;
2196 tail = head + n - 1;
2197 for (i = 0; i < j; i++) {
2198 swap = *head;
2199 *head++ = *tail;
2200 *tail-- = swap;
2201 }
2202
2203 Py_RETURN_NONE;
2204}
2205
2206PyDoc_STRVAR(insert__doc__,
2207"B.insert(index, int) -> None\n\
2208\n\
2209Insert a single item into the bytearray before the given index.");
2210static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002211bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002212{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002213 PyObject *value;
2214 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002215 Py_ssize_t where, n = Py_SIZE(self);
2216
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002217 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002218 return NULL;
2219
2220 if (n == PY_SSIZE_T_MAX) {
2221 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002222 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002223 return NULL;
2224 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002225 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002226 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002227 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2228 return NULL;
2229
2230 if (where < 0) {
2231 where += n;
2232 if (where < 0)
2233 where = 0;
2234 }
2235 if (where > n)
2236 where = n;
2237 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002238 self->ob_bytes[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002239
2240 Py_RETURN_NONE;
2241}
2242
2243PyDoc_STRVAR(append__doc__,
2244"B.append(int) -> None\n\
2245\n\
2246Append a single item to the end of B.");
2247static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002248bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002249{
2250 int value;
2251 Py_ssize_t n = Py_SIZE(self);
2252
2253 if (! _getbytevalue(arg, &value))
2254 return NULL;
2255 if (n == PY_SSIZE_T_MAX) {
2256 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002257 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002258 return NULL;
2259 }
2260 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2261 return NULL;
2262
2263 self->ob_bytes[n] = value;
2264
2265 Py_RETURN_NONE;
2266}
2267
2268PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002269"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002270\n\
2271Append all the elements from the iterator or sequence to the\n\
2272end of B.");
2273static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002274bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002275{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002276 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002277 Py_ssize_t buf_size = 0, len = 0;
2278 int value;
2279 char *buf;
2280
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002281 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002282 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002283 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002284 return NULL;
2285
2286 Py_RETURN_NONE;
2287 }
2288
2289 it = PyObject_GetIter(arg);
2290 if (it == NULL)
2291 return NULL;
2292
Ezio Melotti42da6632011-03-15 05:18:48 +02002293 /* Try to determine the length of the argument. 32 is arbitrary. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002294 buf_size = _PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002295 if (buf_size == -1) {
2296 Py_DECREF(it);
2297 return NULL;
2298 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002299
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002300 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002301 if (bytearray_obj == NULL) {
2302 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002303 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002304 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002305 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002306
2307 while ((item = PyIter_Next(it)) != NULL) {
2308 if (! _getbytevalue(item, &value)) {
2309 Py_DECREF(item);
2310 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002311 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002312 return NULL;
2313 }
2314 buf[len++] = value;
2315 Py_DECREF(item);
2316
2317 if (len >= buf_size) {
2318 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002319 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002320 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002321 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002322 return NULL;
2323 }
2324 /* Recompute the `buf' pointer, since the resizing operation may
2325 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002326 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002327 }
2328 }
2329 Py_DECREF(it);
2330
2331 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002332 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2333 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002334 return NULL;
2335 }
2336
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002337 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2338 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002339 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002340 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002341 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002342
2343 Py_RETURN_NONE;
2344}
2345
2346PyDoc_STRVAR(pop__doc__,
2347"B.pop([index]) -> int\n\
2348\n\
2349Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002350argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002351static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002352bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002353{
2354 int value;
2355 Py_ssize_t where = -1, n = Py_SIZE(self);
2356
2357 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2358 return NULL;
2359
2360 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002361 PyErr_SetString(PyExc_IndexError,
2362 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002363 return NULL;
2364 }
2365 if (where < 0)
2366 where += Py_SIZE(self);
2367 if (where < 0 || where >= Py_SIZE(self)) {
2368 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2369 return NULL;
2370 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002371 if (!_canresize(self))
2372 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002373
2374 value = self->ob_bytes[where];
2375 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2376 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2377 return NULL;
2378
Mark Dickinson54a3db92009-09-06 10:19:23 +00002379 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002380}
2381
2382PyDoc_STRVAR(remove__doc__,
2383"B.remove(int) -> None\n\
2384\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002385Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002386static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002387bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002388{
2389 int value;
2390 Py_ssize_t where, n = Py_SIZE(self);
2391
2392 if (! _getbytevalue(arg, &value))
2393 return NULL;
2394
2395 for (where = 0; where < n; where++) {
2396 if (self->ob_bytes[where] == value)
2397 break;
2398 }
2399 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002400 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002401 return NULL;
2402 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002403 if (!_canresize(self))
2404 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002405
2406 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2407 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2408 return NULL;
2409
2410 Py_RETURN_NONE;
2411}
2412
2413/* XXX These two helpers could be optimized if argsize == 1 */
2414
2415static Py_ssize_t
2416lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2417 void *argptr, Py_ssize_t argsize)
2418{
2419 Py_ssize_t i = 0;
2420 while (i < mysize && memchr(argptr, myptr[i], argsize))
2421 i++;
2422 return i;
2423}
2424
2425static Py_ssize_t
2426rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2427 void *argptr, Py_ssize_t argsize)
2428{
2429 Py_ssize_t i = mysize - 1;
2430 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2431 i--;
2432 return i + 1;
2433}
2434
2435PyDoc_STRVAR(strip__doc__,
2436"B.strip([bytes]) -> bytearray\n\
2437\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002438Strip leading and trailing bytes contained in the argument\n\
2439and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002440If the argument is omitted, strip ASCII whitespace.");
2441static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002442bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002443{
2444 Py_ssize_t left, right, mysize, argsize;
2445 void *myptr, *argptr;
2446 PyObject *arg = Py_None;
2447 Py_buffer varg;
2448 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2449 return NULL;
2450 if (arg == Py_None) {
2451 argptr = "\t\n\r\f\v ";
2452 argsize = 6;
2453 }
2454 else {
2455 if (_getbuffer(arg, &varg) < 0)
2456 return NULL;
2457 argptr = varg.buf;
2458 argsize = varg.len;
2459 }
2460 myptr = self->ob_bytes;
2461 mysize = Py_SIZE(self);
2462 left = lstrip_helper(myptr, mysize, argptr, argsize);
2463 if (left == mysize)
2464 right = left;
2465 else
2466 right = rstrip_helper(myptr, mysize, argptr, argsize);
2467 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002468 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002469 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2470}
2471
2472PyDoc_STRVAR(lstrip__doc__,
2473"B.lstrip([bytes]) -> bytearray\n\
2474\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002475Strip leading bytes contained in the argument\n\
2476and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002477If the argument is omitted, strip leading ASCII whitespace.");
2478static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002479bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002480{
2481 Py_ssize_t left, right, mysize, argsize;
2482 void *myptr, *argptr;
2483 PyObject *arg = Py_None;
2484 Py_buffer varg;
2485 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2486 return NULL;
2487 if (arg == Py_None) {
2488 argptr = "\t\n\r\f\v ";
2489 argsize = 6;
2490 }
2491 else {
2492 if (_getbuffer(arg, &varg) < 0)
2493 return NULL;
2494 argptr = varg.buf;
2495 argsize = varg.len;
2496 }
2497 myptr = self->ob_bytes;
2498 mysize = Py_SIZE(self);
2499 left = lstrip_helper(myptr, mysize, argptr, argsize);
2500 right = mysize;
2501 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002502 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002503 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2504}
2505
2506PyDoc_STRVAR(rstrip__doc__,
2507"B.rstrip([bytes]) -> bytearray\n\
2508\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002509Strip trailing bytes contained in the argument\n\
2510and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002511If the argument is omitted, strip trailing ASCII whitespace.");
2512static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002513bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002514{
Brett Cannonb94767f2011-02-22 20:15:44 +00002515 Py_ssize_t right, mysize, argsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002516 void *myptr, *argptr;
2517 PyObject *arg = Py_None;
2518 Py_buffer varg;
2519 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2520 return NULL;
2521 if (arg == Py_None) {
2522 argptr = "\t\n\r\f\v ";
2523 argsize = 6;
2524 }
2525 else {
2526 if (_getbuffer(arg, &varg) < 0)
2527 return NULL;
2528 argptr = varg.buf;
2529 argsize = varg.len;
2530 }
2531 myptr = self->ob_bytes;
2532 mysize = Py_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002533 right = rstrip_helper(myptr, mysize, argptr, argsize);
2534 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002535 PyBuffer_Release(&varg);
Brett Cannonb94767f2011-02-22 20:15:44 +00002536 return PyByteArray_FromStringAndSize(self->ob_bytes, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002537}
2538
2539PyDoc_STRVAR(decode_doc,
Victor Stinnerc911bbf2010-11-07 19:04:46 +00002540"B.decode(encoding='utf-8', errors='strict') -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002541\n\
Victor Stinnere14e2122010-11-07 18:41:46 +00002542Decode B using the codec registered for encoding. Default encoding\n\
2543is 'utf-8'. errors may be given to set a different error\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002544handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2545a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2546as well as any other name registered with codecs.register_error that is\n\
2547able to handle UnicodeDecodeErrors.");
2548
2549static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002550bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002551{
2552 const char *encoding = NULL;
2553 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002554 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002555
Benjamin Peterson308d6372009-09-18 21:42:35 +00002556 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002557 return NULL;
2558 if (encoding == NULL)
2559 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002560 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002561}
2562
2563PyDoc_STRVAR(alloc_doc,
2564"B.__alloc__() -> int\n\
2565\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002566Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002567
2568static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002569bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002570{
2571 return PyLong_FromSsize_t(self->ob_alloc);
2572}
2573
2574PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002575"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002576\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002577Concatenate any number of bytes/bytearray objects, with B\n\
2578in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002579
2580static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002581bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002582{
2583 PyObject *seq;
2584 Py_ssize_t mysize = Py_SIZE(self);
2585 Py_ssize_t i;
2586 Py_ssize_t n;
2587 PyObject **items;
2588 Py_ssize_t totalsize = 0;
2589 PyObject *result;
2590 char *dest;
2591
2592 seq = PySequence_Fast(it, "can only join an iterable");
2593 if (seq == NULL)
2594 return NULL;
2595 n = PySequence_Fast_GET_SIZE(seq);
2596 items = PySequence_Fast_ITEMS(seq);
2597
2598 /* Compute the total size, and check that they are all bytes */
2599 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2600 for (i = 0; i < n; i++) {
2601 PyObject *obj = items[i];
2602 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2603 PyErr_Format(PyExc_TypeError,
2604 "can only join an iterable of bytes "
2605 "(item %ld has type '%.100s')",
2606 /* XXX %ld isn't right on Win64 */
2607 (long)i, Py_TYPE(obj)->tp_name);
2608 goto error;
2609 }
2610 if (i > 0)
2611 totalsize += mysize;
2612 totalsize += Py_SIZE(obj);
2613 if (totalsize < 0) {
2614 PyErr_NoMemory();
2615 goto error;
2616 }
2617 }
2618
2619 /* Allocate the result, and copy the bytes */
2620 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2621 if (result == NULL)
2622 goto error;
2623 dest = PyByteArray_AS_STRING(result);
2624 for (i = 0; i < n; i++) {
2625 PyObject *obj = items[i];
2626 Py_ssize_t size = Py_SIZE(obj);
2627 char *buf;
2628 if (PyByteArray_Check(obj))
2629 buf = PyByteArray_AS_STRING(obj);
2630 else
2631 buf = PyBytes_AS_STRING(obj);
2632 if (i) {
2633 memcpy(dest, self->ob_bytes, mysize);
2634 dest += mysize;
2635 }
2636 memcpy(dest, buf, size);
2637 dest += size;
2638 }
2639
2640 /* Done */
2641 Py_DECREF(seq);
2642 return result;
2643
2644 /* Error handling */
2645 error:
2646 Py_DECREF(seq);
2647 return NULL;
2648}
2649
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002650PyDoc_STRVAR(splitlines__doc__,
2651"B.splitlines([keepends]) -> list of lines\n\
2652\n\
2653Return a list of the lines in B, breaking at line boundaries.\n\
2654Line breaks are not included in the resulting list unless keepends\n\
2655is given and true.");
2656
2657static PyObject*
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002658bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002659{
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002660 static char *kwlist[] = {"keepends", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002661 int keepends = 0;
2662
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002663 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines",
2664 kwlist, &keepends))
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002665 return NULL;
2666
2667 return stringlib_splitlines(
2668 (PyObject*) self, PyByteArray_AS_STRING(self),
2669 PyByteArray_GET_SIZE(self), keepends
2670 );
2671}
2672
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002673PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002674"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002675\n\
2676Create a bytearray object from a string of hexadecimal numbers.\n\
2677Spaces between two numbers are accepted.\n\
2678Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2679
2680static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002681hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002682{
2683 if (c >= 128)
2684 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002685 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002686 return c - '0';
2687 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002688 if (Py_ISUPPER(c))
2689 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002690 if (c >= 'a' && c <= 'f')
2691 return c - 'a' + 10;
2692 }
2693 return -1;
2694}
2695
2696static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002697bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002698{
2699 PyObject *newbytes, *hexobj;
2700 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002701 Py_ssize_t hexlen, byteslen, i, j;
2702 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002703 void *data;
2704 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002705
2706 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2707 return NULL;
2708 assert(PyUnicode_Check(hexobj));
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002709 if (PyUnicode_READY(hexobj))
2710 return NULL;
2711 kind = PyUnicode_KIND(hexobj);
2712 data = PyUnicode_DATA(hexobj);
2713 hexlen = PyUnicode_GET_LENGTH(hexobj);
2714
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002715 byteslen = hexlen/2; /* This overestimates if there are spaces */
2716 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2717 if (!newbytes)
2718 return NULL;
2719 buf = PyByteArray_AS_STRING(newbytes);
2720 for (i = j = 0; i < hexlen; i += 2) {
2721 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002722 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002723 i++;
2724 if (i >= hexlen)
2725 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002726 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2727 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002728 if (top == -1 || bot == -1) {
2729 PyErr_Format(PyExc_ValueError,
2730 "non-hexadecimal number found in "
2731 "fromhex() arg at position %zd", i);
2732 goto error;
2733 }
2734 buf[j++] = (top << 4) + bot;
2735 }
2736 if (PyByteArray_Resize(newbytes, j) < 0)
2737 goto error;
2738 return newbytes;
2739
2740 error:
2741 Py_DECREF(newbytes);
2742 return NULL;
2743}
2744
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002745
2746static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002747_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002748{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002749 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002750 _Py_IDENTIFIER(__dict__);
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002751
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002752 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002753 if (dict == NULL) {
2754 PyErr_Clear();
2755 dict = Py_None;
2756 Py_INCREF(dict);
2757 }
2758
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002759 if (proto < 3) {
2760 /* use str based reduction for backwards compatibility with Python 2.x */
2761 PyObject *latin1;
2762 if (self->ob_bytes)
2763 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes, Py_SIZE(self), NULL);
2764 else
2765 latin1 = PyUnicode_FromString("");
2766 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2767 }
2768 else {
2769 /* use more efficient byte based reduction */
2770 if (self->ob_bytes) {
2771 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), self->ob_bytes, Py_SIZE(self), dict);
2772 }
2773 else {
2774 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2775 }
2776 }
2777}
2778
2779PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2780
2781static PyObject *
2782bytearray_reduce(PyByteArrayObject *self)
2783{
2784 return _common_reduce(self, 2);
2785}
2786
2787PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling.");
2788
2789static PyObject *
2790bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
2791{
2792 int proto = 0;
2793
2794 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
2795 return NULL;
2796
2797 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002798}
2799
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002800PyDoc_STRVAR(sizeof_doc,
2801"B.__sizeof__() -> int\n\
2802 \n\
2803Returns the size of B in memory, in bytes");
2804static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002805bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002806{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002807 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002808
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002809 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2810 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002811}
2812
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002813static PySequenceMethods bytearray_as_sequence = {
2814 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002815 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002816 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2817 (ssizeargfunc)bytearray_getitem, /* sq_item */
2818 0, /* sq_slice */
2819 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2820 0, /* sq_ass_slice */
2821 (objobjproc)bytearray_contains, /* sq_contains */
2822 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2823 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002824};
2825
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002826static PyMappingMethods bytearray_as_mapping = {
2827 (lenfunc)bytearray_length,
2828 (binaryfunc)bytearray_subscript,
2829 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002830};
2831
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002832static PyBufferProcs bytearray_as_buffer = {
2833 (getbufferproc)bytearray_getbuffer,
2834 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002835};
2836
2837static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002838bytearray_methods[] = {
2839 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2840 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002841 {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002842 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2843 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002844 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2845 _Py_capitalize__doc__},
2846 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00002847 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__},
2848 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002849 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002850 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002851 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002852 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2853 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002854 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2855 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2856 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002857 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002858 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2859 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002860 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2861 _Py_isalnum__doc__},
2862 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2863 _Py_isalpha__doc__},
2864 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2865 _Py_isdigit__doc__},
2866 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2867 _Py_islower__doc__},
2868 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2869 _Py_isspace__doc__},
2870 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2871 _Py_istitle__doc__},
2872 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2873 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002874 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002875 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2876 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002877 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2878 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002879 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002880 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2881 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2882 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2883 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2884 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2885 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2886 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002887 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002888 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002889 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002890 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002891 {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__},
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002892 {"splitlines", (PyCFunction)bytearray_splitlines,
2893 METH_VARARGS | METH_KEYWORDS, splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002894 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002895 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002896 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002897 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2898 _Py_swapcase__doc__},
2899 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002900 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002901 translate__doc__},
2902 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2903 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2904 {NULL}
2905};
2906
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002907PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002908"bytearray(iterable_of_ints) -> bytearray\n\
2909bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002910bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2911bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2912bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002913\n\
2914Construct an mutable bytearray object from:\n\
2915 - an iterable yielding integers in range(256)\n\
2916 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002917 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002918 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002919 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002920
2921
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002922static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002923
2924PyTypeObject PyByteArray_Type = {
2925 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2926 "bytearray",
2927 sizeof(PyByteArrayObject),
2928 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002929 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002930 0, /* tp_print */
2931 0, /* tp_getattr */
2932 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002933 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002934 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002935 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002936 &bytearray_as_sequence, /* tp_as_sequence */
2937 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002938 0, /* tp_hash */
2939 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002940 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002941 PyObject_GenericGetAttr, /* tp_getattro */
2942 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002943 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002944 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002945 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002946 0, /* tp_traverse */
2947 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002948 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002949 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002950 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002951 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002952 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002953 0, /* tp_members */
2954 0, /* tp_getset */
2955 0, /* tp_base */
2956 0, /* tp_dict */
2957 0, /* tp_descr_get */
2958 0, /* tp_descr_set */
2959 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002960 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002961 PyType_GenericAlloc, /* tp_alloc */
2962 PyType_GenericNew, /* tp_new */
2963 PyObject_Del, /* tp_free */
2964};
2965
2966/*********************** Bytes Iterator ****************************/
2967
2968typedef struct {
2969 PyObject_HEAD
2970 Py_ssize_t it_index;
2971 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2972} bytesiterobject;
2973
2974static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002975bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002976{
2977 _PyObject_GC_UNTRACK(it);
2978 Py_XDECREF(it->it_seq);
2979 PyObject_GC_Del(it);
2980}
2981
2982static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002983bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002984{
2985 Py_VISIT(it->it_seq);
2986 return 0;
2987}
2988
2989static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002990bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002991{
2992 PyByteArrayObject *seq;
2993 PyObject *item;
2994
2995 assert(it != NULL);
2996 seq = it->it_seq;
2997 if (seq == NULL)
2998 return NULL;
2999 assert(PyByteArray_Check(seq));
3000
3001 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
3002 item = PyLong_FromLong(
3003 (unsigned char)seq->ob_bytes[it->it_index]);
3004 if (item != NULL)
3005 ++it->it_index;
3006 return item;
3007 }
3008
3009 Py_DECREF(seq);
3010 it->it_seq = NULL;
3011 return NULL;
3012}
3013
3014static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003015bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003016{
3017 Py_ssize_t len = 0;
3018 if (it->it_seq)
3019 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3020 return PyLong_FromSsize_t(len);
3021}
3022
3023PyDoc_STRVAR(length_hint_doc,
3024 "Private method returning an estimate of len(list(it)).");
3025
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003026static PyObject *
3027bytearrayiter_reduce(bytesiterobject *it)
3028{
3029 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02003030 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003031 it->it_seq, it->it_index);
3032 } else {
3033 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
3034 if (u == NULL)
3035 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02003036 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003037 }
3038}
3039
3040static PyObject *
3041bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3042{
3043 Py_ssize_t index = PyLong_AsSsize_t(state);
3044 if (index == -1 && PyErr_Occurred())
3045 return NULL;
3046 if (index < 0)
3047 index = 0;
3048 it->it_index = index;
3049 Py_RETURN_NONE;
3050}
3051
3052PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3053
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003054static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003055 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003056 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003057 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
3058 reduce_doc},
3059 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3060 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003061 {NULL, NULL} /* sentinel */
3062};
3063
3064PyTypeObject PyByteArrayIter_Type = {
3065 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3066 "bytearray_iterator", /* tp_name */
3067 sizeof(bytesiterobject), /* tp_basicsize */
3068 0, /* tp_itemsize */
3069 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003070 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003071 0, /* tp_print */
3072 0, /* tp_getattr */
3073 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003074 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003075 0, /* tp_repr */
3076 0, /* tp_as_number */
3077 0, /* tp_as_sequence */
3078 0, /* tp_as_mapping */
3079 0, /* tp_hash */
3080 0, /* tp_call */
3081 0, /* tp_str */
3082 PyObject_GenericGetAttr, /* tp_getattro */
3083 0, /* tp_setattro */
3084 0, /* tp_as_buffer */
3085 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3086 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003087 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003088 0, /* tp_clear */
3089 0, /* tp_richcompare */
3090 0, /* tp_weaklistoffset */
3091 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003092 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3093 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003094 0,
3095};
3096
3097static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003098bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003099{
3100 bytesiterobject *it;
3101
3102 if (!PyByteArray_Check(seq)) {
3103 PyErr_BadInternalCall();
3104 return NULL;
3105 }
3106 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3107 if (it == NULL)
3108 return NULL;
3109 it->it_index = 0;
3110 Py_INCREF(seq);
3111 it->it_seq = (PyByteArrayObject *)seq;
3112 _PyObject_GC_TRACK(it);
3113 return (PyObject *)it;
3114}