blob: a98ecdde5c9a0d578063418bfef754e57701eb27 [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)) {
Georg Brandlf3fa5682010-12-04 17:09:30 +0000592 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000593 int err;
594 values = PyByteArray_FromObject(values);
595 if (values == NULL)
596 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000597 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000598 Py_DECREF(values);
599 return err;
600 }
601 else {
602 assert(PyByteArray_Check(values));
603 bytes = ((PyByteArrayObject *)values)->ob_bytes;
604 needed = Py_SIZE(values);
605 }
606 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
607 if ((step < 0 && start < stop) ||
608 (step > 0 && start > stop))
609 stop = start;
610 if (step == 1) {
611 if (slicelen != needed) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000612 if (!_canresize(self))
613 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000614 if (slicelen > needed) {
615 /*
616 0 start stop old_size
617 | |<---slicelen--->|<-----tomove------>|
618 | |<-needed->|<-----tomove------>|
619 0 lo new_hi new_size
620 */
621 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
622 Py_SIZE(self) - stop);
623 }
624 if (PyByteArray_Resize((PyObject *)self,
625 Py_SIZE(self) + needed - slicelen) < 0)
626 return -1;
627 if (slicelen < needed) {
628 /*
629 0 lo hi old_size
630 | |<-avail->|<-----tomove------>|
631 | |<----needed---->|<-----tomove------>|
632 0 lo new_hi new_size
633 */
634 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
635 Py_SIZE(self) - start - needed);
636 }
637 }
638
639 if (needed > 0)
640 memcpy(self->ob_bytes + start, bytes, needed);
641
642 return 0;
643 }
644 else {
645 if (needed == 0) {
646 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000647 size_t cur;
648 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000649
Antoine Pitrou5504e892008-12-06 21:27:53 +0000650 if (!_canresize(self))
651 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000652
653 if (slicelen == 0)
654 /* Nothing to do here. */
655 return 0;
656
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000657 if (step < 0) {
658 stop = start + 1;
659 start = stop + step * (slicelen - 1) - 1;
660 step = -step;
661 }
662 for (cur = start, i = 0;
663 i < slicelen; cur += step, i++) {
664 Py_ssize_t lim = step - 1;
665
Mark Dickinson66f575b2010-02-14 12:53:32 +0000666 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000667 lim = PyByteArray_GET_SIZE(self) - cur - 1;
668
669 memmove(self->ob_bytes + cur - i,
670 self->ob_bytes + cur + 1, lim);
671 }
672 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000673 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000674 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000675 memmove(self->ob_bytes + cur - slicelen,
676 self->ob_bytes + cur,
677 PyByteArray_GET_SIZE(self) - cur);
678 }
679 if (PyByteArray_Resize((PyObject *)self,
680 PyByteArray_GET_SIZE(self) - slicelen) < 0)
681 return -1;
682
683 return 0;
684 }
685 else {
686 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000687 Py_ssize_t i;
688 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000689
690 if (needed != slicelen) {
691 PyErr_Format(PyExc_ValueError,
692 "attempt to assign bytes of size %zd "
693 "to extended slice of size %zd",
694 needed, slicelen);
695 return -1;
696 }
697 for (cur = start, i = 0; i < slicelen; cur += step, i++)
698 self->ob_bytes[cur] = bytes[i];
699 return 0;
700 }
701 }
702}
703
704static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000705bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000706{
707 static char *kwlist[] = {"source", "encoding", "errors", 0};
708 PyObject *arg = NULL;
709 const char *encoding = NULL;
710 const char *errors = NULL;
711 Py_ssize_t count;
712 PyObject *it;
713 PyObject *(*iternext)(PyObject *);
714
715 if (Py_SIZE(self) != 0) {
716 /* Empty previous contents (yes, do this first of all!) */
717 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
718 return -1;
719 }
720
721 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000722 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000723 &arg, &encoding, &errors))
724 return -1;
725
726 /* Make a quick exit if no first argument */
727 if (arg == NULL) {
728 if (encoding != NULL || errors != NULL) {
729 PyErr_SetString(PyExc_TypeError,
730 "encoding or errors without sequence argument");
731 return -1;
732 }
733 return 0;
734 }
735
736 if (PyUnicode_Check(arg)) {
737 /* Encode via the codec registry */
738 PyObject *encoded, *new;
739 if (encoding == NULL) {
740 PyErr_SetString(PyExc_TypeError,
741 "string argument without an encoding");
742 return -1;
743 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000744 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000745 if (encoded == NULL)
746 return -1;
747 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000748 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000749 Py_DECREF(encoded);
750 if (new == NULL)
751 return -1;
752 Py_DECREF(new);
753 return 0;
754 }
755
756 /* If it's not unicode, there can't be encoding or errors */
757 if (encoding != NULL || errors != NULL) {
758 PyErr_SetString(PyExc_TypeError,
759 "encoding or errors without a string argument");
760 return -1;
761 }
762
763 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000764 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
765 if (count == -1 && PyErr_Occurred()) {
766 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000767 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000768 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000769 }
770 else if (count < 0) {
771 PyErr_SetString(PyExc_ValueError, "negative count");
772 return -1;
773 }
774 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000775 if (count > 0) {
776 if (PyByteArray_Resize((PyObject *)self, count))
777 return -1;
778 memset(self->ob_bytes, 0, count);
779 }
780 return 0;
781 }
782
783 /* Use the buffer API */
784 if (PyObject_CheckBuffer(arg)) {
785 Py_ssize_t size;
786 Py_buffer view;
787 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
788 return -1;
789 size = view.len;
790 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
791 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200792 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000793 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000794 return 0;
795 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000796 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000797 return -1;
798 }
799
800 /* XXX Optimize this if the arguments is a list, tuple */
801
802 /* Get the iterator */
803 it = PyObject_GetIter(arg);
804 if (it == NULL)
805 return -1;
806 iternext = *Py_TYPE(it)->tp_iternext;
807
808 /* Run the iterator to exhaustion */
809 for (;;) {
810 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000811 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000812
813 /* Get the next item */
814 item = iternext(it);
815 if (item == NULL) {
816 if (PyErr_Occurred()) {
817 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
818 goto error;
819 PyErr_Clear();
820 }
821 break;
822 }
823
824 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000825 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000826 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000827 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000828 goto error;
829
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000830 /* Append the byte */
831 if (Py_SIZE(self) < self->ob_alloc)
832 Py_SIZE(self)++;
833 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
834 goto error;
835 self->ob_bytes[Py_SIZE(self)-1] = value;
836 }
837
838 /* Clean up and return success */
839 Py_DECREF(it);
840 return 0;
841
842 error:
843 /* Error handling when it != NULL */
844 Py_DECREF(it);
845 return -1;
846}
847
848/* Mostly copied from string_repr, but without the
849 "smart quote" functionality. */
850static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000851bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000852{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000853 const char *quote_prefix = "bytearray(b";
854 const char *quote_postfix = ")";
855 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200856 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000857 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000858 PyObject *v;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200859 register Py_ssize_t i;
860 register char c;
861 register char *p;
862 int quote;
863 char *test, *start;
864 char *buffer;
865
866 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000867 PyErr_SetString(PyExc_OverflowError,
868 "bytearray object is too large to make repr");
869 return NULL;
870 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200871
872 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100873 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200874 if (buffer == NULL) {
875 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000876 return NULL;
877 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000878
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200879 /* Figure out which quote to use; single is preferred */
880 quote = '\'';
881 start = PyByteArray_AS_STRING(self);
882 for (test = start; test < start+length; ++test) {
883 if (*test == '"') {
884 quote = '\''; /* back to single */
885 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000886 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200887 else if (*test == '\'')
888 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000889 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200890
891 p = buffer;
892 while (*quote_prefix)
893 *p++ = *quote_prefix++;
894 *p++ = quote;
895
896 for (i = 0; i < length; i++) {
897 /* There's at least enough room for a hex escape
898 and a closing quote. */
899 assert(newsize - (p - buffer) >= 5);
900 c = self->ob_bytes[i];
901 if (c == '\'' || c == '\\')
902 *p++ = '\\', *p++ = c;
903 else if (c == '\t')
904 *p++ = '\\', *p++ = 't';
905 else if (c == '\n')
906 *p++ = '\\', *p++ = 'n';
907 else if (c == '\r')
908 *p++ = '\\', *p++ = 'r';
909 else if (c == 0)
910 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
911 else if (c < ' ' || c >= 0x7f) {
912 *p++ = '\\';
913 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200914 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
915 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200916 }
917 else
918 *p++ = c;
919 }
920 assert(newsize - (p - buffer) >= 1);
921 *p++ = quote;
922 while (*quote_postfix) {
923 *p++ = *quote_postfix++;
924 }
925
926 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100927 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200928 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000929}
930
931static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000932bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000933{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000934 if (Py_BytesWarningFlag) {
935 if (PyErr_WarnEx(PyExc_BytesWarning,
936 "str() on a bytearray instance", 1))
937 return NULL;
938 }
939 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000940}
941
942static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000943bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000944{
945 Py_ssize_t self_size, other_size;
946 Py_buffer self_bytes, other_bytes;
947 PyObject *res;
948 Py_ssize_t minsize;
949 int cmp;
950
951 /* Bytes can be compared to anything that supports the (binary)
952 buffer API. Except that a comparison with Unicode is always an
953 error, even if the comparison is for equality. */
954 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
955 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000956 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000957 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000958 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000959 return NULL;
960 }
961
Brian Curtindfc80e32011-08-10 20:28:54 -0500962 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000963 }
964
965 self_size = _getbuffer(self, &self_bytes);
966 if (self_size < 0) {
967 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -0500968 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000969 }
970
971 other_size = _getbuffer(other, &other_bytes);
972 if (other_size < 0) {
973 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +0000974 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -0500975 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000976 }
977
978 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
979 /* Shortcut: if the lengths differ, the objects differ */
980 cmp = (op == Py_NE);
981 }
982 else {
983 minsize = self_size;
984 if (other_size < minsize)
985 minsize = other_size;
986
987 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
988 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
989
990 if (cmp == 0) {
991 if (self_size < other_size)
992 cmp = -1;
993 else if (self_size > other_size)
994 cmp = 1;
995 }
996
997 switch (op) {
998 case Py_LT: cmp = cmp < 0; break;
999 case Py_LE: cmp = cmp <= 0; break;
1000 case Py_EQ: cmp = cmp == 0; break;
1001 case Py_NE: cmp = cmp != 0; break;
1002 case Py_GT: cmp = cmp > 0; break;
1003 case Py_GE: cmp = cmp >= 0; break;
1004 }
1005 }
1006
1007 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001008 PyBuffer_Release(&self_bytes);
1009 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001010 Py_INCREF(res);
1011 return res;
1012}
1013
1014static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001015bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001016{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001017 if (self->ob_exports > 0) {
1018 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001019 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001020 PyErr_Print();
1021 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001022 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001023 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001024 }
1025 Py_TYPE(self)->tp_free((PyObject *)self);
1026}
1027
1028
1029/* -------------------------------------------------------------------- */
1030/* Methods */
1031
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001032#define FASTSEARCH fastsearch
1033#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001034#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001035#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001036#define STRINGLIB_LEN PyByteArray_GET_SIZE
1037#define STRINGLIB_STR PyByteArray_AS_STRING
1038#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001039#define STRINGLIB_ISSPACE Py_ISSPACE
1040#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001041#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1042#define STRINGLIB_MUTABLE 1
1043
1044#include "stringlib/fastsearch.h"
1045#include "stringlib/count.h"
1046#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001047#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001048#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001049#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001050#include "stringlib/ctype.h"
1051#include "stringlib/transmogrify.h"
1052
1053
1054/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1055were copied from the old char* style string object. */
1056
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001057/* helper macro to fixup start/end slice values */
1058#define ADJUST_INDICES(start, end, len) \
1059 if (end > len) \
1060 end = len; \
1061 else if (end < 0) { \
1062 end += len; \
1063 if (end < 0) \
1064 end = 0; \
1065 } \
1066 if (start < 0) { \
1067 start += len; \
1068 if (start < 0) \
1069 start = 0; \
1070 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001071
1072Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001073bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001074{
1075 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001076 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001077 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001078 const char *sub;
1079 Py_ssize_t sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001080 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1081 Py_ssize_t res;
1082
Antoine Pitrouac65d962011-10-20 23:54:17 +02001083 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1084 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001085 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001086
1087 if (subobj) {
1088 if (_getbuffer(subobj, &subbuf) < 0)
1089 return -2;
1090
1091 sub = subbuf.buf;
1092 sub_len = subbuf.len;
1093 }
1094 else {
1095 sub = &byte;
1096 sub_len = 1;
1097 }
1098
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001099 if (dir > 0)
1100 res = stringlib_find_slice(
1101 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001102 sub, sub_len, start, end);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001103 else
1104 res = stringlib_rfind_slice(
1105 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001106 sub, sub_len, start, end);
1107
1108 if (subobj)
1109 PyBuffer_Release(&subbuf);
1110
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001111 return res;
1112}
1113
1114PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001115"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001116\n\
1117Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001118such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001119arguments start and end are interpreted as in slice notation.\n\
1120\n\
1121Return -1 on failure.");
1122
1123static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001124bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001125{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001126 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001127 if (result == -2)
1128 return NULL;
1129 return PyLong_FromSsize_t(result);
1130}
1131
1132PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001133"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001134\n\
1135Return the number of non-overlapping occurrences of subsection sub in\n\
1136bytes B[start:end]. Optional arguments start and end are interpreted\n\
1137as in slice notation.");
1138
1139static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001140bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001141{
1142 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001143 const char *str = PyByteArray_AS_STRING(self), *sub;
1144 Py_ssize_t sub_len;
1145 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001146 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001147
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001148 Py_buffer vsub;
1149 PyObject *count_obj;
1150
Antoine Pitrouac65d962011-10-20 23:54:17 +02001151 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1152 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001153 return NULL;
1154
Antoine Pitrouac65d962011-10-20 23:54:17 +02001155 if (sub_obj) {
1156 if (_getbuffer(sub_obj, &vsub) < 0)
1157 return NULL;
1158
1159 sub = vsub.buf;
1160 sub_len = vsub.len;
1161 }
1162 else {
1163 sub = &byte;
1164 sub_len = 1;
1165 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001166
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001167 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001168
1169 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001170 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001171 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001172
1173 if (sub_obj)
1174 PyBuffer_Release(&vsub);
1175
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001176 return count_obj;
1177}
1178
Eli Bendersky4db28d32011-03-03 18:21:02 +00001179PyDoc_STRVAR(clear__doc__,
1180"B.clear() -> None\n\
1181\n\
1182Remove all items from B.");
1183
Victor Stinner6430fd52011-09-29 04:02:13 +02001184static PyObject *
Eli Bendersky4db28d32011-03-03 18:21:02 +00001185bytearray_clear(PyByteArrayObject *self)
1186{
1187 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1188 return NULL;
1189 Py_RETURN_NONE;
1190}
1191
1192PyDoc_STRVAR(copy__doc__,
1193"B.copy() -> bytearray\n\
1194\n\
1195Return a copy of B.");
1196
1197static PyObject *
1198bytearray_copy(PyByteArrayObject *self)
1199{
1200 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1201 PyByteArray_GET_SIZE(self));
1202}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001203
1204PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001205"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001206\n\
1207Like B.find() but raise ValueError when the subsection is not found.");
1208
1209static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001210bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001211{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001212 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001213 if (result == -2)
1214 return NULL;
1215 if (result == -1) {
1216 PyErr_SetString(PyExc_ValueError,
1217 "subsection not found");
1218 return NULL;
1219 }
1220 return PyLong_FromSsize_t(result);
1221}
1222
1223
1224PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001225"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001226\n\
1227Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001228such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001229arguments start and end are interpreted as in slice notation.\n\
1230\n\
1231Return -1 on failure.");
1232
1233static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001234bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001235{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001236 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001237 if (result == -2)
1238 return NULL;
1239 return PyLong_FromSsize_t(result);
1240}
1241
1242
1243PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001244"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001245\n\
1246Like B.rfind() but raise ValueError when the subsection is not found.");
1247
1248static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001249bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001250{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001251 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001252 if (result == -2)
1253 return NULL;
1254 if (result == -1) {
1255 PyErr_SetString(PyExc_ValueError,
1256 "subsection not found");
1257 return NULL;
1258 }
1259 return PyLong_FromSsize_t(result);
1260}
1261
1262
1263static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001264bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001265{
1266 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1267 if (ival == -1 && PyErr_Occurred()) {
1268 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001269 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001270 PyErr_Clear();
1271 if (_getbuffer(arg, &varg) < 0)
1272 return -1;
1273 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1274 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001275 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001276 return pos >= 0;
1277 }
1278 if (ival < 0 || ival >= 256) {
1279 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1280 return -1;
1281 }
1282
Antoine Pitrou0010d372010-08-15 17:12:55 +00001283 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001284}
1285
1286
1287/* Matches the end (direction >= 0) or start (direction < 0) of self
1288 * against substr, using the start and end arguments. Returns
1289 * -1 on error, 0 if not found and 1 if found.
1290 */
1291Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001292_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001293 Py_ssize_t end, int direction)
1294{
1295 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1296 const char* str;
1297 Py_buffer vsubstr;
1298 int rv = 0;
1299
1300 str = PyByteArray_AS_STRING(self);
1301
1302 if (_getbuffer(substr, &vsubstr) < 0)
1303 return -1;
1304
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001305 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001306
1307 if (direction < 0) {
1308 /* startswith */
1309 if (start+vsubstr.len > len) {
1310 goto done;
1311 }
1312 } else {
1313 /* endswith */
1314 if (end-start < vsubstr.len || start > len) {
1315 goto done;
1316 }
1317
1318 if (end-vsubstr.len > start)
1319 start = end - vsubstr.len;
1320 }
1321 if (end-start >= vsubstr.len)
1322 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1323
1324done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001325 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001326 return rv;
1327}
1328
1329
1330PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001331"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001332\n\
1333Return True if B starts with the specified prefix, False otherwise.\n\
1334With optional start, test B beginning at that position.\n\
1335With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001336prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001337
1338static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001339bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001340{
1341 Py_ssize_t start = 0;
1342 Py_ssize_t end = PY_SSIZE_T_MAX;
1343 PyObject *subobj;
1344 int result;
1345
Jesus Ceaac451502011-04-20 17:09:23 +02001346 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001347 return NULL;
1348 if (PyTuple_Check(subobj)) {
1349 Py_ssize_t i;
1350 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001351 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001352 PyTuple_GET_ITEM(subobj, i),
1353 start, end, -1);
1354 if (result == -1)
1355 return NULL;
1356 else if (result) {
1357 Py_RETURN_TRUE;
1358 }
1359 }
1360 Py_RETURN_FALSE;
1361 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001362 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001363 if (result == -1) {
1364 if (PyErr_ExceptionMatches(PyExc_TypeError))
1365 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1366 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001367 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001368 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001369 else
1370 return PyBool_FromLong(result);
1371}
1372
1373PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001374"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001375\n\
1376Return True if B ends with the specified suffix, False otherwise.\n\
1377With optional start, test B beginning at that position.\n\
1378With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001379suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001380
1381static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001382bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001383{
1384 Py_ssize_t start = 0;
1385 Py_ssize_t end = PY_SSIZE_T_MAX;
1386 PyObject *subobj;
1387 int result;
1388
Jesus Ceaac451502011-04-20 17:09:23 +02001389 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001390 return NULL;
1391 if (PyTuple_Check(subobj)) {
1392 Py_ssize_t i;
1393 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001394 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001395 PyTuple_GET_ITEM(subobj, i),
1396 start, end, +1);
1397 if (result == -1)
1398 return NULL;
1399 else if (result) {
1400 Py_RETURN_TRUE;
1401 }
1402 }
1403 Py_RETURN_FALSE;
1404 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001405 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001406 if (result == -1) {
1407 if (PyErr_ExceptionMatches(PyExc_TypeError))
1408 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1409 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001410 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001411 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001412 else
1413 return PyBool_FromLong(result);
1414}
1415
1416
1417PyDoc_STRVAR(translate__doc__,
1418"B.translate(table[, deletechars]) -> bytearray\n\
1419\n\
1420Return a copy of B, where all characters occurring in the\n\
1421optional argument deletechars are removed, and the remaining\n\
1422characters have been mapped through the given translation\n\
1423table, which must be a bytes object of length 256.");
1424
1425static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001426bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001427{
1428 register char *input, *output;
1429 register const char *table;
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001430 register Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001431 PyObject *input_obj = (PyObject*)self;
1432 const char *output_start;
1433 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001434 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001435 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001436 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001437 Py_buffer vtable, vdel;
1438
1439 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1440 &tableobj, &delobj))
1441 return NULL;
1442
Georg Brandlccc47b62008-12-28 11:44:14 +00001443 if (tableobj == Py_None) {
1444 table = NULL;
1445 tableobj = NULL;
1446 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001447 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001448 } else {
1449 if (vtable.len != 256) {
1450 PyErr_SetString(PyExc_ValueError,
1451 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001452 PyBuffer_Release(&vtable);
1453 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001454 }
1455 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001456 }
1457
1458 if (delobj != NULL) {
1459 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001460 if (tableobj != NULL)
1461 PyBuffer_Release(&vtable);
1462 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001463 }
1464 }
1465 else {
1466 vdel.buf = NULL;
1467 vdel.len = 0;
1468 }
1469
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001470 inlen = PyByteArray_GET_SIZE(input_obj);
1471 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1472 if (result == NULL)
1473 goto done;
1474 output_start = output = PyByteArray_AsString(result);
1475 input = PyByteArray_AS_STRING(input_obj);
1476
Georg Brandlccc47b62008-12-28 11:44:14 +00001477 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001478 /* If no deletions are required, use faster code */
1479 for (i = inlen; --i >= 0; ) {
1480 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001481 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001482 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001483 goto done;
1484 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001485
1486 if (table == NULL) {
1487 for (i = 0; i < 256; i++)
1488 trans_table[i] = Py_CHARMASK(i);
1489 } else {
1490 for (i = 0; i < 256; i++)
1491 trans_table[i] = Py_CHARMASK(table[i]);
1492 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001493
1494 for (i = 0; i < vdel.len; i++)
1495 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1496
1497 for (i = inlen; --i >= 0; ) {
1498 c = Py_CHARMASK(*input++);
1499 if (trans_table[c] != -1)
1500 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1501 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001502 }
1503 /* Fix the size of the resulting string */
1504 if (inlen > 0)
1505 PyByteArray_Resize(result, output - output_start);
1506
1507done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001508 if (tableobj != NULL)
1509 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001510 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001511 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001512 return result;
1513}
1514
1515
Georg Brandlabc38772009-04-12 15:51:51 +00001516static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001517bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001518{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001519 return _Py_bytes_maketrans(args);
Georg Brandlabc38772009-04-12 15:51:51 +00001520}
1521
1522
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001523/* find and count characters and substrings */
1524
1525#define findchar(target, target_len, c) \
1526 ((char *)memchr((const void *)(target), c, target_len))
1527
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001528
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001529/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001530Py_LOCAL(PyByteArrayObject *)
1531return_self(PyByteArrayObject *self)
1532{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001533 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001534 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1535 PyByteArray_AS_STRING(self),
1536 PyByteArray_GET_SIZE(self));
1537}
1538
1539Py_LOCAL_INLINE(Py_ssize_t)
1540countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1541{
1542 Py_ssize_t count=0;
1543 const char *start=target;
1544 const char *end=target+target_len;
1545
1546 while ( (start=findchar(start, end-start, c)) != NULL ) {
1547 count++;
1548 if (count >= maxcount)
1549 break;
1550 start += 1;
1551 }
1552 return count;
1553}
1554
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001555
1556/* Algorithms for different cases of string replacement */
1557
1558/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1559Py_LOCAL(PyByteArrayObject *)
1560replace_interleave(PyByteArrayObject *self,
1561 const char *to_s, Py_ssize_t to_len,
1562 Py_ssize_t maxcount)
1563{
1564 char *self_s, *result_s;
1565 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001566 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001567 PyByteArrayObject *result;
1568
1569 self_len = PyByteArray_GET_SIZE(self);
1570
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001571 /* 1 at the end plus 1 after every character;
1572 count = min(maxcount, self_len + 1) */
1573 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001574 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001575 else
1576 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1577 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001578
1579 /* Check for overflow */
1580 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001581 assert(count > 0);
1582 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001583 PyErr_SetString(PyExc_OverflowError,
1584 "replace string is too long");
1585 return NULL;
1586 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001587 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001588
1589 if (! (result = (PyByteArrayObject *)
1590 PyByteArray_FromStringAndSize(NULL, result_len)) )
1591 return NULL;
1592
1593 self_s = PyByteArray_AS_STRING(self);
1594 result_s = PyByteArray_AS_STRING(result);
1595
1596 /* TODO: special case single character, which doesn't need memcpy */
1597
1598 /* Lay the first one down (guaranteed this will occur) */
1599 Py_MEMCPY(result_s, to_s, to_len);
1600 result_s += to_len;
1601 count -= 1;
1602
1603 for (i=0; i<count; i++) {
1604 *result_s++ = *self_s++;
1605 Py_MEMCPY(result_s, to_s, to_len);
1606 result_s += to_len;
1607 }
1608
1609 /* Copy the rest of the original string */
1610 Py_MEMCPY(result_s, self_s, self_len-i);
1611
1612 return result;
1613}
1614
1615/* Special case for deleting a single character */
1616/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1617Py_LOCAL(PyByteArrayObject *)
1618replace_delete_single_character(PyByteArrayObject *self,
1619 char from_c, Py_ssize_t maxcount)
1620{
1621 char *self_s, *result_s;
1622 char *start, *next, *end;
1623 Py_ssize_t self_len, result_len;
1624 Py_ssize_t count;
1625 PyByteArrayObject *result;
1626
1627 self_len = PyByteArray_GET_SIZE(self);
1628 self_s = PyByteArray_AS_STRING(self);
1629
1630 count = countchar(self_s, self_len, from_c, maxcount);
1631 if (count == 0) {
1632 return return_self(self);
1633 }
1634
1635 result_len = self_len - count; /* from_len == 1 */
1636 assert(result_len>=0);
1637
1638 if ( (result = (PyByteArrayObject *)
1639 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1640 return NULL;
1641 result_s = PyByteArray_AS_STRING(result);
1642
1643 start = self_s;
1644 end = self_s + self_len;
1645 while (count-- > 0) {
1646 next = findchar(start, end-start, from_c);
1647 if (next == NULL)
1648 break;
1649 Py_MEMCPY(result_s, start, next-start);
1650 result_s += (next-start);
1651 start = next+1;
1652 }
1653 Py_MEMCPY(result_s, start, end-start);
1654
1655 return result;
1656}
1657
1658/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1659
1660Py_LOCAL(PyByteArrayObject *)
1661replace_delete_substring(PyByteArrayObject *self,
1662 const char *from_s, Py_ssize_t from_len,
1663 Py_ssize_t maxcount)
1664{
1665 char *self_s, *result_s;
1666 char *start, *next, *end;
1667 Py_ssize_t self_len, result_len;
1668 Py_ssize_t count, offset;
1669 PyByteArrayObject *result;
1670
1671 self_len = PyByteArray_GET_SIZE(self);
1672 self_s = PyByteArray_AS_STRING(self);
1673
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001674 count = stringlib_count(self_s, self_len,
1675 from_s, from_len,
1676 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001677
1678 if (count == 0) {
1679 /* no matches */
1680 return return_self(self);
1681 }
1682
1683 result_len = self_len - (count * from_len);
1684 assert (result_len>=0);
1685
1686 if ( (result = (PyByteArrayObject *)
1687 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1688 return NULL;
1689
1690 result_s = PyByteArray_AS_STRING(result);
1691
1692 start = self_s;
1693 end = self_s + self_len;
1694 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001695 offset = stringlib_find(start, end-start,
1696 from_s, from_len,
1697 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001698 if (offset == -1)
1699 break;
1700 next = start + offset;
1701
1702 Py_MEMCPY(result_s, start, next-start);
1703
1704 result_s += (next-start);
1705 start = next+from_len;
1706 }
1707 Py_MEMCPY(result_s, start, end-start);
1708 return result;
1709}
1710
1711/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1712Py_LOCAL(PyByteArrayObject *)
1713replace_single_character_in_place(PyByteArrayObject *self,
1714 char from_c, char to_c,
1715 Py_ssize_t maxcount)
1716{
Antoine Pitroud1188562010-06-09 16:38:55 +00001717 char *self_s, *result_s, *start, *end, *next;
1718 Py_ssize_t self_len;
1719 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001720
Antoine Pitroud1188562010-06-09 16:38:55 +00001721 /* The result string will be the same size */
1722 self_s = PyByteArray_AS_STRING(self);
1723 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001724
Antoine Pitroud1188562010-06-09 16:38:55 +00001725 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001726
Antoine Pitroud1188562010-06-09 16:38:55 +00001727 if (next == NULL) {
1728 /* No matches; return the original bytes */
1729 return return_self(self);
1730 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001731
Antoine Pitroud1188562010-06-09 16:38:55 +00001732 /* Need to make a new bytes */
1733 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1734 if (result == NULL)
1735 return NULL;
1736 result_s = PyByteArray_AS_STRING(result);
1737 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001738
Antoine Pitroud1188562010-06-09 16:38:55 +00001739 /* change everything in-place, starting with this one */
1740 start = result_s + (next-self_s);
1741 *start = to_c;
1742 start++;
1743 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001744
Antoine Pitroud1188562010-06-09 16:38:55 +00001745 while (--maxcount > 0) {
1746 next = findchar(start, end-start, from_c);
1747 if (next == NULL)
1748 break;
1749 *next = to_c;
1750 start = next+1;
1751 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001752
Antoine Pitroud1188562010-06-09 16:38:55 +00001753 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001754}
1755
1756/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1757Py_LOCAL(PyByteArrayObject *)
1758replace_substring_in_place(PyByteArrayObject *self,
1759 const char *from_s, Py_ssize_t from_len,
1760 const char *to_s, Py_ssize_t to_len,
1761 Py_ssize_t maxcount)
1762{
1763 char *result_s, *start, *end;
1764 char *self_s;
1765 Py_ssize_t self_len, offset;
1766 PyByteArrayObject *result;
1767
1768 /* The result bytes will be the same size */
1769
1770 self_s = PyByteArray_AS_STRING(self);
1771 self_len = PyByteArray_GET_SIZE(self);
1772
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001773 offset = stringlib_find(self_s, self_len,
1774 from_s, from_len,
1775 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001776 if (offset == -1) {
1777 /* No matches; return the original bytes */
1778 return return_self(self);
1779 }
1780
1781 /* Need to make a new bytes */
1782 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1783 if (result == NULL)
1784 return NULL;
1785 result_s = PyByteArray_AS_STRING(result);
1786 Py_MEMCPY(result_s, self_s, self_len);
1787
1788 /* change everything in-place, starting with this one */
1789 start = result_s + offset;
1790 Py_MEMCPY(start, to_s, from_len);
1791 start += from_len;
1792 end = result_s + self_len;
1793
1794 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001795 offset = stringlib_find(start, end-start,
1796 from_s, from_len,
1797 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001798 if (offset==-1)
1799 break;
1800 Py_MEMCPY(start+offset, to_s, from_len);
1801 start += offset+from_len;
1802 }
1803
1804 return result;
1805}
1806
1807/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1808Py_LOCAL(PyByteArrayObject *)
1809replace_single_character(PyByteArrayObject *self,
1810 char from_c,
1811 const char *to_s, Py_ssize_t to_len,
1812 Py_ssize_t maxcount)
1813{
1814 char *self_s, *result_s;
1815 char *start, *next, *end;
1816 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001817 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001818 PyByteArrayObject *result;
1819
1820 self_s = PyByteArray_AS_STRING(self);
1821 self_len = PyByteArray_GET_SIZE(self);
1822
1823 count = countchar(self_s, self_len, from_c, maxcount);
1824 if (count == 0) {
1825 /* no matches, return unchanged */
1826 return return_self(self);
1827 }
1828
1829 /* use the difference between current and new, hence the "-1" */
1830 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001831 assert(count > 0);
1832 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001833 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1834 return NULL;
1835 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001836 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001837
1838 if ( (result = (PyByteArrayObject *)
1839 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1840 return NULL;
1841 result_s = PyByteArray_AS_STRING(result);
1842
1843 start = self_s;
1844 end = self_s + self_len;
1845 while (count-- > 0) {
1846 next = findchar(start, end-start, from_c);
1847 if (next == NULL)
1848 break;
1849
1850 if (next == start) {
1851 /* replace with the 'to' */
1852 Py_MEMCPY(result_s, to_s, to_len);
1853 result_s += to_len;
1854 start += 1;
1855 } else {
1856 /* copy the unchanged old then the 'to' */
1857 Py_MEMCPY(result_s, start, next-start);
1858 result_s += (next-start);
1859 Py_MEMCPY(result_s, to_s, to_len);
1860 result_s += to_len;
1861 start = next+1;
1862 }
1863 }
1864 /* Copy the remainder of the remaining bytes */
1865 Py_MEMCPY(result_s, start, end-start);
1866
1867 return result;
1868}
1869
1870/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1871Py_LOCAL(PyByteArrayObject *)
1872replace_substring(PyByteArrayObject *self,
1873 const char *from_s, Py_ssize_t from_len,
1874 const char *to_s, Py_ssize_t to_len,
1875 Py_ssize_t maxcount)
1876{
1877 char *self_s, *result_s;
1878 char *start, *next, *end;
1879 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001880 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001881 PyByteArrayObject *result;
1882
1883 self_s = PyByteArray_AS_STRING(self);
1884 self_len = PyByteArray_GET_SIZE(self);
1885
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001886 count = stringlib_count(self_s, self_len,
1887 from_s, from_len,
1888 maxcount);
1889
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001890 if (count == 0) {
1891 /* no matches, return unchanged */
1892 return return_self(self);
1893 }
1894
1895 /* Check for overflow */
1896 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001897 assert(count > 0);
1898 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001899 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1900 return NULL;
1901 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001902 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001903
1904 if ( (result = (PyByteArrayObject *)
1905 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1906 return NULL;
1907 result_s = PyByteArray_AS_STRING(result);
1908
1909 start = self_s;
1910 end = self_s + self_len;
1911 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001912 offset = stringlib_find(start, end-start,
1913 from_s, from_len,
1914 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001915 if (offset == -1)
1916 break;
1917 next = start+offset;
1918 if (next == start) {
1919 /* replace with the 'to' */
1920 Py_MEMCPY(result_s, to_s, to_len);
1921 result_s += to_len;
1922 start += from_len;
1923 } else {
1924 /* copy the unchanged old then the 'to' */
1925 Py_MEMCPY(result_s, start, next-start);
1926 result_s += (next-start);
1927 Py_MEMCPY(result_s, to_s, to_len);
1928 result_s += to_len;
1929 start = next+from_len;
1930 }
1931 }
1932 /* Copy the remainder of the remaining bytes */
1933 Py_MEMCPY(result_s, start, end-start);
1934
1935 return result;
1936}
1937
1938
1939Py_LOCAL(PyByteArrayObject *)
1940replace(PyByteArrayObject *self,
1941 const char *from_s, Py_ssize_t from_len,
1942 const char *to_s, Py_ssize_t to_len,
1943 Py_ssize_t maxcount)
1944{
1945 if (maxcount < 0) {
1946 maxcount = PY_SSIZE_T_MAX;
1947 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1948 /* nothing to do; return the original bytes */
1949 return return_self(self);
1950 }
1951
1952 if (maxcount == 0 ||
1953 (from_len == 0 && to_len == 0)) {
1954 /* nothing to do; return the original bytes */
1955 return return_self(self);
1956 }
1957
1958 /* Handle zero-length special cases */
1959
1960 if (from_len == 0) {
1961 /* insert the 'to' bytes everywhere. */
1962 /* >>> "Python".replace("", ".") */
1963 /* '.P.y.t.h.o.n.' */
1964 return replace_interleave(self, to_s, to_len, maxcount);
1965 }
1966
1967 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1968 /* point for an empty self bytes to generate a non-empty bytes */
1969 /* Special case so the remaining code always gets a non-empty bytes */
1970 if (PyByteArray_GET_SIZE(self) == 0) {
1971 return return_self(self);
1972 }
1973
1974 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00001975 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001976 if (from_len == 1) {
1977 return replace_delete_single_character(
1978 self, from_s[0], maxcount);
1979 } else {
1980 return replace_delete_substring(self, from_s, from_len, maxcount);
1981 }
1982 }
1983
1984 /* Handle special case where both bytes have the same length */
1985
1986 if (from_len == to_len) {
1987 if (from_len == 1) {
1988 return replace_single_character_in_place(
1989 self,
1990 from_s[0],
1991 to_s[0],
1992 maxcount);
1993 } else {
1994 return replace_substring_in_place(
1995 self, from_s, from_len, to_s, to_len, maxcount);
1996 }
1997 }
1998
1999 /* Otherwise use the more generic algorithms */
2000 if (from_len == 1) {
2001 return replace_single_character(self, from_s[0],
2002 to_s, to_len, maxcount);
2003 } else {
2004 /* len('from')>=2, len('to')>=1 */
2005 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2006 }
2007}
2008
2009
2010PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002011"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002012\n\
2013Return a copy of B with all occurrences of subsection\n\
2014old replaced by new. If the optional argument count is\n\
2015given, only the first count occurrences are replaced.");
2016
2017static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002018bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002019{
2020 Py_ssize_t count = -1;
2021 PyObject *from, *to, *res;
2022 Py_buffer vfrom, vto;
2023
2024 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2025 return NULL;
2026
2027 if (_getbuffer(from, &vfrom) < 0)
2028 return NULL;
2029 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +00002030 PyBuffer_Release(&vfrom);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002031 return NULL;
2032 }
2033
2034 res = (PyObject *)replace((PyByteArrayObject *) self,
2035 vfrom.buf, vfrom.len,
2036 vto.buf, vto.len, count);
2037
Martin v. Löwis423be952008-08-13 15:53:07 +00002038 PyBuffer_Release(&vfrom);
2039 PyBuffer_Release(&vto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002040 return res;
2041}
2042
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002043PyDoc_STRVAR(split__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002044"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002045\n\
2046Return a list of the sections in B, using sep as the delimiter.\n\
2047If sep is not given, B is split on ASCII whitespace characters\n\
2048(space, tab, return, newline, formfeed, vertical tab).\n\
2049If maxsplit is given, at most maxsplit splits are done.");
2050
2051static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002052bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002053{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002054 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002055 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2056 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002057 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002058 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002059 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002060
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002061 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
2062 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002063 return NULL;
2064 if (maxsplit < 0)
2065 maxsplit = PY_SSIZE_T_MAX;
2066
2067 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002068 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002069
2070 if (_getbuffer(subobj, &vsub) < 0)
2071 return NULL;
2072 sub = vsub.buf;
2073 n = vsub.len;
2074
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002075 list = stringlib_split(
2076 (PyObject*) self, s, len, sub, n, maxsplit
2077 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002078 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002079 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002080}
2081
2082PyDoc_STRVAR(partition__doc__,
2083"B.partition(sep) -> (head, sep, tail)\n\
2084\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002085Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002086the separator itself, and the part after it. If the separator is not\n\
2087found, returns B and two empty bytearray objects.");
2088
2089static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002090bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002091{
2092 PyObject *bytesep, *result;
2093
2094 bytesep = PyByteArray_FromObject(sep_obj);
2095 if (! bytesep)
2096 return NULL;
2097
2098 result = stringlib_partition(
2099 (PyObject*) self,
2100 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2101 bytesep,
2102 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2103 );
2104
2105 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002106 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002107}
2108
2109PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002110"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002111\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002112Search for the separator sep in B, starting at the end of B,\n\
2113and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002114part after it. If the separator is not found, returns two empty\n\
2115bytearray objects and B.");
2116
2117static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002118bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002119{
2120 PyObject *bytesep, *result;
2121
2122 bytesep = PyByteArray_FromObject(sep_obj);
2123 if (! bytesep)
2124 return NULL;
2125
2126 result = stringlib_rpartition(
2127 (PyObject*) self,
2128 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2129 bytesep,
2130 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2131 );
2132
2133 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002134 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002135}
2136
2137PyDoc_STRVAR(rsplit__doc__,
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002138"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002139\n\
2140Return a list of the sections in B, using sep as the delimiter,\n\
2141starting at the end of B and working to the front.\n\
2142If sep is not given, B is split on ASCII whitespace characters\n\
2143(space, tab, return, newline, formfeed, vertical tab).\n\
2144If maxsplit is given, at most maxsplit splits are done.");
2145
2146static PyObject *
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002147bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002148{
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002149 static char *kwlist[] = {"sep", "maxsplit", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002150 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2151 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002152 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002153 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002154 Py_buffer vsub;
2155
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002156 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit",
2157 kwlist, &subobj, &maxsplit))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002158 return NULL;
2159 if (maxsplit < 0)
2160 maxsplit = PY_SSIZE_T_MAX;
2161
2162 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002163 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002164
2165 if (_getbuffer(subobj, &vsub) < 0)
2166 return NULL;
2167 sub = vsub.buf;
2168 n = vsub.len;
2169
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002170 list = stringlib_rsplit(
2171 (PyObject*) self, s, len, sub, n, maxsplit
2172 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002173 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002174 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002175}
2176
2177PyDoc_STRVAR(reverse__doc__,
2178"B.reverse() -> None\n\
2179\n\
2180Reverse the order of the values in B in place.");
2181static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002182bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002183{
2184 char swap, *head, *tail;
2185 Py_ssize_t i, j, n = Py_SIZE(self);
2186
2187 j = n / 2;
2188 head = self->ob_bytes;
2189 tail = head + n - 1;
2190 for (i = 0; i < j; i++) {
2191 swap = *head;
2192 *head++ = *tail;
2193 *tail-- = swap;
2194 }
2195
2196 Py_RETURN_NONE;
2197}
2198
2199PyDoc_STRVAR(insert__doc__,
2200"B.insert(index, int) -> None\n\
2201\n\
2202Insert a single item into the bytearray before the given index.");
2203static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002204bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002205{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002206 PyObject *value;
2207 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002208 Py_ssize_t where, n = Py_SIZE(self);
2209
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002210 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002211 return NULL;
2212
2213 if (n == PY_SSIZE_T_MAX) {
2214 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002215 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002216 return NULL;
2217 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002218 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002219 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002220 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2221 return NULL;
2222
2223 if (where < 0) {
2224 where += n;
2225 if (where < 0)
2226 where = 0;
2227 }
2228 if (where > n)
2229 where = n;
2230 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002231 self->ob_bytes[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002232
2233 Py_RETURN_NONE;
2234}
2235
2236PyDoc_STRVAR(append__doc__,
2237"B.append(int) -> None\n\
2238\n\
2239Append a single item to the end of B.");
2240static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002241bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002242{
2243 int value;
2244 Py_ssize_t n = Py_SIZE(self);
2245
2246 if (! _getbytevalue(arg, &value))
2247 return NULL;
2248 if (n == PY_SSIZE_T_MAX) {
2249 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002250 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002251 return NULL;
2252 }
2253 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2254 return NULL;
2255
2256 self->ob_bytes[n] = value;
2257
2258 Py_RETURN_NONE;
2259}
2260
2261PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002262"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002263\n\
2264Append all the elements from the iterator or sequence to the\n\
2265end of B.");
2266static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002267bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002268{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002269 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002270 Py_ssize_t buf_size = 0, len = 0;
2271 int value;
2272 char *buf;
2273
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002274 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002275 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002276 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002277 return NULL;
2278
2279 Py_RETURN_NONE;
2280 }
2281
2282 it = PyObject_GetIter(arg);
2283 if (it == NULL)
2284 return NULL;
2285
Ezio Melotti42da6632011-03-15 05:18:48 +02002286 /* Try to determine the length of the argument. 32 is arbitrary. */
Armin Ronacheraa9a79d2012-10-06 14:03:24 +02002287 buf_size = PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002288 if (buf_size == -1) {
2289 Py_DECREF(it);
2290 return NULL;
2291 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002292
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002293 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002294 if (bytearray_obj == NULL) {
2295 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002296 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002297 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002298 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002299
2300 while ((item = PyIter_Next(it)) != NULL) {
2301 if (! _getbytevalue(item, &value)) {
2302 Py_DECREF(item);
2303 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002304 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002305 return NULL;
2306 }
2307 buf[len++] = value;
2308 Py_DECREF(item);
2309
2310 if (len >= buf_size) {
2311 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002312 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002313 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002314 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002315 return NULL;
2316 }
2317 /* Recompute the `buf' pointer, since the resizing operation may
2318 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002319 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002320 }
2321 }
2322 Py_DECREF(it);
2323
2324 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002325 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2326 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002327 return NULL;
2328 }
2329
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002330 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2331 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002332 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002333 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002334 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002335
2336 Py_RETURN_NONE;
2337}
2338
2339PyDoc_STRVAR(pop__doc__,
2340"B.pop([index]) -> int\n\
2341\n\
2342Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002343argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002344static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002345bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002346{
2347 int value;
2348 Py_ssize_t where = -1, n = Py_SIZE(self);
2349
2350 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2351 return NULL;
2352
2353 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002354 PyErr_SetString(PyExc_IndexError,
2355 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002356 return NULL;
2357 }
2358 if (where < 0)
2359 where += Py_SIZE(self);
2360 if (where < 0 || where >= Py_SIZE(self)) {
2361 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2362 return NULL;
2363 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002364 if (!_canresize(self))
2365 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002366
2367 value = self->ob_bytes[where];
2368 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2369 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2370 return NULL;
2371
Mark Dickinson54a3db92009-09-06 10:19:23 +00002372 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002373}
2374
2375PyDoc_STRVAR(remove__doc__,
2376"B.remove(int) -> None\n\
2377\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002378Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002379static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002380bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002381{
2382 int value;
2383 Py_ssize_t where, n = Py_SIZE(self);
2384
2385 if (! _getbytevalue(arg, &value))
2386 return NULL;
2387
2388 for (where = 0; where < n; where++) {
2389 if (self->ob_bytes[where] == value)
2390 break;
2391 }
2392 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002393 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002394 return NULL;
2395 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002396 if (!_canresize(self))
2397 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002398
2399 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2400 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2401 return NULL;
2402
2403 Py_RETURN_NONE;
2404}
2405
2406/* XXX These two helpers could be optimized if argsize == 1 */
2407
2408static Py_ssize_t
2409lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2410 void *argptr, Py_ssize_t argsize)
2411{
2412 Py_ssize_t i = 0;
2413 while (i < mysize && memchr(argptr, myptr[i], argsize))
2414 i++;
2415 return i;
2416}
2417
2418static Py_ssize_t
2419rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2420 void *argptr, Py_ssize_t argsize)
2421{
2422 Py_ssize_t i = mysize - 1;
2423 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2424 i--;
2425 return i + 1;
2426}
2427
2428PyDoc_STRVAR(strip__doc__,
2429"B.strip([bytes]) -> bytearray\n\
2430\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002431Strip leading and trailing bytes contained in the argument\n\
2432and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002433If the argument is omitted, strip ASCII whitespace.");
2434static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002435bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002436{
2437 Py_ssize_t left, right, mysize, argsize;
2438 void *myptr, *argptr;
2439 PyObject *arg = Py_None;
2440 Py_buffer varg;
2441 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2442 return NULL;
2443 if (arg == Py_None) {
2444 argptr = "\t\n\r\f\v ";
2445 argsize = 6;
2446 }
2447 else {
2448 if (_getbuffer(arg, &varg) < 0)
2449 return NULL;
2450 argptr = varg.buf;
2451 argsize = varg.len;
2452 }
2453 myptr = self->ob_bytes;
2454 mysize = Py_SIZE(self);
2455 left = lstrip_helper(myptr, mysize, argptr, argsize);
2456 if (left == mysize)
2457 right = left;
2458 else
2459 right = rstrip_helper(myptr, mysize, argptr, argsize);
2460 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002461 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002462 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2463}
2464
2465PyDoc_STRVAR(lstrip__doc__,
2466"B.lstrip([bytes]) -> bytearray\n\
2467\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002468Strip leading bytes contained in the argument\n\
2469and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002470If the argument is omitted, strip leading ASCII whitespace.");
2471static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002472bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002473{
2474 Py_ssize_t left, right, mysize, argsize;
2475 void *myptr, *argptr;
2476 PyObject *arg = Py_None;
2477 Py_buffer varg;
2478 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2479 return NULL;
2480 if (arg == Py_None) {
2481 argptr = "\t\n\r\f\v ";
2482 argsize = 6;
2483 }
2484 else {
2485 if (_getbuffer(arg, &varg) < 0)
2486 return NULL;
2487 argptr = varg.buf;
2488 argsize = varg.len;
2489 }
2490 myptr = self->ob_bytes;
2491 mysize = Py_SIZE(self);
2492 left = lstrip_helper(myptr, mysize, argptr, argsize);
2493 right = mysize;
2494 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002495 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002496 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2497}
2498
2499PyDoc_STRVAR(rstrip__doc__,
2500"B.rstrip([bytes]) -> bytearray\n\
2501\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002502Strip trailing bytes contained in the argument\n\
2503and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002504If the argument is omitted, strip trailing ASCII whitespace.");
2505static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002506bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002507{
Brett Cannonb94767f2011-02-22 20:15:44 +00002508 Py_ssize_t right, mysize, argsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002509 void *myptr, *argptr;
2510 PyObject *arg = Py_None;
2511 Py_buffer varg;
2512 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2513 return NULL;
2514 if (arg == Py_None) {
2515 argptr = "\t\n\r\f\v ";
2516 argsize = 6;
2517 }
2518 else {
2519 if (_getbuffer(arg, &varg) < 0)
2520 return NULL;
2521 argptr = varg.buf;
2522 argsize = varg.len;
2523 }
2524 myptr = self->ob_bytes;
2525 mysize = Py_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002526 right = rstrip_helper(myptr, mysize, argptr, argsize);
2527 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002528 PyBuffer_Release(&varg);
Brett Cannonb94767f2011-02-22 20:15:44 +00002529 return PyByteArray_FromStringAndSize(self->ob_bytes, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002530}
2531
2532PyDoc_STRVAR(decode_doc,
Victor Stinnerc911bbf2010-11-07 19:04:46 +00002533"B.decode(encoding='utf-8', errors='strict') -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002534\n\
Victor Stinnere14e2122010-11-07 18:41:46 +00002535Decode B using the codec registered for encoding. Default encoding\n\
2536is 'utf-8'. errors may be given to set a different error\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002537handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2538a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2539as well as any other name registered with codecs.register_error that is\n\
2540able to handle UnicodeDecodeErrors.");
2541
2542static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002543bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002544{
2545 const char *encoding = NULL;
2546 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002547 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002548
Benjamin Peterson308d6372009-09-18 21:42:35 +00002549 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002550 return NULL;
2551 if (encoding == NULL)
2552 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002553 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002554}
2555
2556PyDoc_STRVAR(alloc_doc,
2557"B.__alloc__() -> int\n\
2558\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002559Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002560
2561static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002562bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002563{
2564 return PyLong_FromSsize_t(self->ob_alloc);
2565}
2566
2567PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002568"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002569\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002570Concatenate any number of bytes/bytearray objects, with B\n\
2571in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002572
2573static PyObject *
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002574bytearray_join(PyObject *self, PyObject *iterable)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002575{
Antoine Pitroucfc22b42012-10-16 21:07:23 +02002576 return stringlib_bytes_join(self, iterable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002577}
2578
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002579PyDoc_STRVAR(splitlines__doc__,
2580"B.splitlines([keepends]) -> list of lines\n\
2581\n\
2582Return a list of the lines in B, breaking at line boundaries.\n\
2583Line breaks are not included in the resulting list unless keepends\n\
2584is given and true.");
2585
2586static PyObject*
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002587bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002588{
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002589 static char *kwlist[] = {"keepends", 0};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002590 int keepends = 0;
2591
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002592 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines",
2593 kwlist, &keepends))
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002594 return NULL;
2595
2596 return stringlib_splitlines(
2597 (PyObject*) self, PyByteArray_AS_STRING(self),
2598 PyByteArray_GET_SIZE(self), keepends
2599 );
2600}
2601
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002602PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002603"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002604\n\
2605Create a bytearray object from a string of hexadecimal numbers.\n\
2606Spaces between two numbers are accepted.\n\
2607Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2608
2609static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002610hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002611{
2612 if (c >= 128)
2613 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002614 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002615 return c - '0';
2616 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002617 if (Py_ISUPPER(c))
2618 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002619 if (c >= 'a' && c <= 'f')
2620 return c - 'a' + 10;
2621 }
2622 return -1;
2623}
2624
2625static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002626bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002627{
2628 PyObject *newbytes, *hexobj;
2629 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002630 Py_ssize_t hexlen, byteslen, i, j;
2631 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002632 void *data;
2633 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002634
2635 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2636 return NULL;
2637 assert(PyUnicode_Check(hexobj));
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002638 if (PyUnicode_READY(hexobj))
2639 return NULL;
2640 kind = PyUnicode_KIND(hexobj);
2641 data = PyUnicode_DATA(hexobj);
2642 hexlen = PyUnicode_GET_LENGTH(hexobj);
2643
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002644 byteslen = hexlen/2; /* This overestimates if there are spaces */
2645 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2646 if (!newbytes)
2647 return NULL;
2648 buf = PyByteArray_AS_STRING(newbytes);
2649 for (i = j = 0; i < hexlen; i += 2) {
2650 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002651 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002652 i++;
2653 if (i >= hexlen)
2654 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002655 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2656 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002657 if (top == -1 || bot == -1) {
2658 PyErr_Format(PyExc_ValueError,
2659 "non-hexadecimal number found in "
2660 "fromhex() arg at position %zd", i);
2661 goto error;
2662 }
2663 buf[j++] = (top << 4) + bot;
2664 }
2665 if (PyByteArray_Resize(newbytes, j) < 0)
2666 goto error;
2667 return newbytes;
2668
2669 error:
2670 Py_DECREF(newbytes);
2671 return NULL;
2672}
2673
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002674
2675static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002676_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002677{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002678 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002679 _Py_IDENTIFIER(__dict__);
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002680
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002681 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002682 if (dict == NULL) {
2683 PyErr_Clear();
2684 dict = Py_None;
2685 Py_INCREF(dict);
2686 }
2687
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002688 if (proto < 3) {
2689 /* use str based reduction for backwards compatibility with Python 2.x */
2690 PyObject *latin1;
2691 if (self->ob_bytes)
2692 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes, Py_SIZE(self), NULL);
2693 else
2694 latin1 = PyUnicode_FromString("");
2695 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2696 }
2697 else {
2698 /* use more efficient byte based reduction */
2699 if (self->ob_bytes) {
2700 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), self->ob_bytes, Py_SIZE(self), dict);
2701 }
2702 else {
2703 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2704 }
2705 }
2706}
2707
2708PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2709
2710static PyObject *
2711bytearray_reduce(PyByteArrayObject *self)
2712{
2713 return _common_reduce(self, 2);
2714}
2715
2716PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling.");
2717
2718static PyObject *
2719bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
2720{
2721 int proto = 0;
2722
2723 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
2724 return NULL;
2725
2726 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002727}
2728
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002729PyDoc_STRVAR(sizeof_doc,
2730"B.__sizeof__() -> int\n\
2731 \n\
2732Returns the size of B in memory, in bytes");
2733static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002734bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002735{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002736 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002737
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002738 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2739 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002740}
2741
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002742static PySequenceMethods bytearray_as_sequence = {
2743 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002744 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002745 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2746 (ssizeargfunc)bytearray_getitem, /* sq_item */
2747 0, /* sq_slice */
2748 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2749 0, /* sq_ass_slice */
2750 (objobjproc)bytearray_contains, /* sq_contains */
2751 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2752 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002753};
2754
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002755static PyMappingMethods bytearray_as_mapping = {
2756 (lenfunc)bytearray_length,
2757 (binaryfunc)bytearray_subscript,
2758 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002759};
2760
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002761static PyBufferProcs bytearray_as_buffer = {
2762 (getbufferproc)bytearray_getbuffer,
2763 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002764};
2765
2766static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002767bytearray_methods[] = {
2768 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2769 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002770 {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002771 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2772 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002773 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2774 _Py_capitalize__doc__},
2775 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00002776 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__},
2777 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002778 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002779 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002780 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002781 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2782 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002783 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2784 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2785 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002786 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002787 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2788 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002789 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2790 _Py_isalnum__doc__},
2791 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2792 _Py_isalpha__doc__},
2793 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2794 _Py_isdigit__doc__},
2795 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2796 _Py_islower__doc__},
2797 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2798 _Py_isspace__doc__},
2799 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2800 _Py_istitle__doc__},
2801 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2802 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002803 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002804 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2805 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002806 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2807 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002808 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002809 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2810 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2811 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2812 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2813 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2814 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2815 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002816 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002817 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002818 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002819 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
Ezio Melotticda6b6d2012-02-26 09:39:55 +02002820 {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__},
Mark Dickinson0d5f6ad2011-09-24 09:14:39 +01002821 {"splitlines", (PyCFunction)bytearray_splitlines,
2822 METH_VARARGS | METH_KEYWORDS, splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002823 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002824 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002825 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002826 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2827 _Py_swapcase__doc__},
2828 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002829 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002830 translate__doc__},
2831 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2832 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2833 {NULL}
2834};
2835
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002836PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002837"bytearray(iterable_of_ints) -> bytearray\n\
2838bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002839bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2840bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2841bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002842\n\
2843Construct an mutable bytearray object from:\n\
2844 - an iterable yielding integers in range(256)\n\
2845 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002846 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002847 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002848 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002849
2850
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002851static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002852
2853PyTypeObject PyByteArray_Type = {
2854 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2855 "bytearray",
2856 sizeof(PyByteArrayObject),
2857 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002858 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002859 0, /* tp_print */
2860 0, /* tp_getattr */
2861 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002862 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002863 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002864 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002865 &bytearray_as_sequence, /* tp_as_sequence */
2866 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002867 0, /* tp_hash */
2868 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002869 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002870 PyObject_GenericGetAttr, /* tp_getattro */
2871 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002872 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002873 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002874 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002875 0, /* tp_traverse */
2876 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002877 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002878 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002879 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002880 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002881 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002882 0, /* tp_members */
2883 0, /* tp_getset */
2884 0, /* tp_base */
2885 0, /* tp_dict */
2886 0, /* tp_descr_get */
2887 0, /* tp_descr_set */
2888 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002889 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002890 PyType_GenericAlloc, /* tp_alloc */
2891 PyType_GenericNew, /* tp_new */
2892 PyObject_Del, /* tp_free */
2893};
2894
2895/*********************** Bytes Iterator ****************************/
2896
2897typedef struct {
2898 PyObject_HEAD
2899 Py_ssize_t it_index;
2900 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2901} bytesiterobject;
2902
2903static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002904bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002905{
2906 _PyObject_GC_UNTRACK(it);
2907 Py_XDECREF(it->it_seq);
2908 PyObject_GC_Del(it);
2909}
2910
2911static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002912bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002913{
2914 Py_VISIT(it->it_seq);
2915 return 0;
2916}
2917
2918static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002919bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002920{
2921 PyByteArrayObject *seq;
2922 PyObject *item;
2923
2924 assert(it != NULL);
2925 seq = it->it_seq;
2926 if (seq == NULL)
2927 return NULL;
2928 assert(PyByteArray_Check(seq));
2929
2930 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2931 item = PyLong_FromLong(
2932 (unsigned char)seq->ob_bytes[it->it_index]);
2933 if (item != NULL)
2934 ++it->it_index;
2935 return item;
2936 }
2937
2938 Py_DECREF(seq);
2939 it->it_seq = NULL;
2940 return NULL;
2941}
2942
2943static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002944bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002945{
2946 Py_ssize_t len = 0;
2947 if (it->it_seq)
2948 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2949 return PyLong_FromSsize_t(len);
2950}
2951
2952PyDoc_STRVAR(length_hint_doc,
2953 "Private method returning an estimate of len(list(it)).");
2954
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002955static PyObject *
2956bytearrayiter_reduce(bytesiterobject *it)
2957{
2958 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02002959 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002960 it->it_seq, it->it_index);
2961 } else {
2962 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
2963 if (u == NULL)
2964 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02002965 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002966 }
2967}
2968
2969static PyObject *
2970bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
2971{
2972 Py_ssize_t index = PyLong_AsSsize_t(state);
2973 if (index == -1 && PyErr_Occurred())
2974 return NULL;
2975 if (index < 0)
2976 index = 0;
2977 it->it_index = index;
2978 Py_RETURN_NONE;
2979}
2980
2981PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
2982
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002983static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002984 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002985 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002986 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
2987 reduce_doc},
2988 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
2989 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002990 {NULL, NULL} /* sentinel */
2991};
2992
2993PyTypeObject PyByteArrayIter_Type = {
2994 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2995 "bytearray_iterator", /* tp_name */
2996 sizeof(bytesiterobject), /* tp_basicsize */
2997 0, /* tp_itemsize */
2998 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002999 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003000 0, /* tp_print */
3001 0, /* tp_getattr */
3002 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003003 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003004 0, /* tp_repr */
3005 0, /* tp_as_number */
3006 0, /* tp_as_sequence */
3007 0, /* tp_as_mapping */
3008 0, /* tp_hash */
3009 0, /* tp_call */
3010 0, /* tp_str */
3011 PyObject_GenericGetAttr, /* tp_getattro */
3012 0, /* tp_setattro */
3013 0, /* tp_as_buffer */
3014 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3015 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003016 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003017 0, /* tp_clear */
3018 0, /* tp_richcompare */
3019 0, /* tp_weaklistoffset */
3020 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003021 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3022 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003023 0,
3024};
3025
3026static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003027bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003028{
3029 bytesiterobject *it;
3030
3031 if (!PyByteArray_Check(seq)) {
3032 PyErr_BadInternalCall();
3033 return NULL;
3034 }
3035 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3036 if (it == NULL)
3037 return NULL;
3038 it->it_index = 0;
3039 Py_INCREF(seq);
3040 it->it_seq = (PyByteArrayObject *)seq;
3041 _PyObject_GC_TRACK(it);
3042 return (PyObject *)it;
3043}