blob: 827fdedb43d3d4f13dad4d36b382ac9dd648a540 [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;
142 new->ob_bytes = PyMem_Malloc(alloc);
143 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
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000212 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
213 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)
792 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{
853 static const char *hexdigits = "0123456789abcdef";
854 const char *quote_prefix = "bytearray(b";
855 const char *quote_postfix = ")";
856 Py_ssize_t length = Py_SIZE(self);
857 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000858 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000859 PyObject *v;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000860 if (length > (PY_SSIZE_T_MAX - 14) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000861 PyErr_SetString(PyExc_OverflowError,
862 "bytearray object is too large to make repr");
863 return NULL;
864 }
Mark Dickinson66f575b2010-02-14 12:53:32 +0000865 newsize = 14 + 4 * length;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000866 v = PyUnicode_FromUnicode(NULL, newsize);
867 if (v == NULL) {
868 return NULL;
869 }
870 else {
871 register Py_ssize_t i;
872 register Py_UNICODE c;
873 register Py_UNICODE *p;
874 int quote;
875
876 /* Figure out which quote to use; single is preferred */
877 quote = '\'';
878 {
879 char *test, *start;
880 start = PyByteArray_AS_STRING(self);
881 for (test = start; test < start+length; ++test) {
882 if (*test == '"') {
883 quote = '\''; /* back to single */
884 goto decided;
885 }
886 else if (*test == '\'')
887 quote = '"';
888 }
889 decided:
890 ;
891 }
892
893 p = PyUnicode_AS_UNICODE(v);
894 while (*quote_prefix)
895 *p++ = *quote_prefix++;
896 *p++ = quote;
897
898 for (i = 0; i < length; i++) {
899 /* There's at least enough room for a hex escape
900 and a closing quote. */
901 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5);
902 c = self->ob_bytes[i];
903 if (c == '\'' || c == '\\')
904 *p++ = '\\', *p++ = c;
905 else if (c == '\t')
906 *p++ = '\\', *p++ = 't';
907 else if (c == '\n')
908 *p++ = '\\', *p++ = 'n';
909 else if (c == '\r')
910 *p++ = '\\', *p++ = 'r';
911 else if (c == 0)
912 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
913 else if (c < ' ' || c >= 0x7f) {
914 *p++ = '\\';
915 *p++ = 'x';
916 *p++ = hexdigits[(c & 0xf0) >> 4];
917 *p++ = hexdigits[c & 0xf];
918 }
919 else
920 *p++ = c;
921 }
922 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1);
923 *p++ = quote;
924 while (*quote_postfix) {
925 *p++ = *quote_postfix++;
926 }
927 *p = '\0';
928 if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
929 Py_DECREF(v);
930 return NULL;
931 }
932 return v;
933 }
934}
935
936static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000937bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000938{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000939 if (Py_BytesWarningFlag) {
940 if (PyErr_WarnEx(PyExc_BytesWarning,
941 "str() on a bytearray instance", 1))
942 return NULL;
943 }
944 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000945}
946
947static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000948bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000949{
950 Py_ssize_t self_size, other_size;
951 Py_buffer self_bytes, other_bytes;
952 PyObject *res;
953 Py_ssize_t minsize;
954 int cmp;
955
956 /* Bytes can be compared to anything that supports the (binary)
957 buffer API. Except that a comparison with Unicode is always an
958 error, even if the comparison is for equality. */
959 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
960 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000961 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000962 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000963 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000964 return NULL;
965 }
966
967 Py_INCREF(Py_NotImplemented);
968 return Py_NotImplemented;
969 }
970
971 self_size = _getbuffer(self, &self_bytes);
972 if (self_size < 0) {
973 PyErr_Clear();
974 Py_INCREF(Py_NotImplemented);
975 return Py_NotImplemented;
976 }
977
978 other_size = _getbuffer(other, &other_bytes);
979 if (other_size < 0) {
980 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +0000981 PyBuffer_Release(&self_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000982 Py_INCREF(Py_NotImplemented);
983 return Py_NotImplemented;
984 }
985
986 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
987 /* Shortcut: if the lengths differ, the objects differ */
988 cmp = (op == Py_NE);
989 }
990 else {
991 minsize = self_size;
992 if (other_size < minsize)
993 minsize = other_size;
994
995 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
996 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
997
998 if (cmp == 0) {
999 if (self_size < other_size)
1000 cmp = -1;
1001 else if (self_size > other_size)
1002 cmp = 1;
1003 }
1004
1005 switch (op) {
1006 case Py_LT: cmp = cmp < 0; break;
1007 case Py_LE: cmp = cmp <= 0; break;
1008 case Py_EQ: cmp = cmp == 0; break;
1009 case Py_NE: cmp = cmp != 0; break;
1010 case Py_GT: cmp = cmp > 0; break;
1011 case Py_GE: cmp = cmp >= 0; break;
1012 }
1013 }
1014
1015 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001016 PyBuffer_Release(&self_bytes);
1017 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001018 Py_INCREF(res);
1019 return res;
1020}
1021
1022static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001023bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001024{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001025 if (self->ob_exports > 0) {
1026 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001027 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001028 PyErr_Print();
1029 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001030 if (self->ob_bytes != 0) {
1031 PyMem_Free(self->ob_bytes);
1032 }
1033 Py_TYPE(self)->tp_free((PyObject *)self);
1034}
1035
1036
1037/* -------------------------------------------------------------------- */
1038/* Methods */
1039
1040#define STRINGLIB_CHAR char
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001041#define STRINGLIB_LEN PyByteArray_GET_SIZE
1042#define STRINGLIB_STR PyByteArray_AS_STRING
1043#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001044#define STRINGLIB_ISSPACE Py_ISSPACE
1045#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001046#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1047#define STRINGLIB_MUTABLE 1
1048
1049#include "stringlib/fastsearch.h"
1050#include "stringlib/count.h"
1051#include "stringlib/find.h"
1052#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001053#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001054#include "stringlib/ctype.h"
1055#include "stringlib/transmogrify.h"
1056
1057
1058/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1059were copied from the old char* style string object. */
1060
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001061/* helper macro to fixup start/end slice values */
1062#define ADJUST_INDICES(start, end, len) \
1063 if (end > len) \
1064 end = len; \
1065 else if (end < 0) { \
1066 end += len; \
1067 if (end < 0) \
1068 end = 0; \
1069 } \
1070 if (start < 0) { \
1071 start += len; \
1072 if (start < 0) \
1073 start = 0; \
1074 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001075
1076Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001077bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001078{
1079 PyObject *subobj;
1080 Py_buffer subbuf;
1081 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1082 Py_ssize_t res;
1083
Jesus Ceaac451502011-04-20 17:09:23 +02001084 if (!stringlib_parse_args_finds("find/rfind/index/rindex",
1085 args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001086 return -2;
1087 if (_getbuffer(subobj, &subbuf) < 0)
1088 return -2;
1089 if (dir > 0)
1090 res = stringlib_find_slice(
1091 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1092 subbuf.buf, subbuf.len, start, end);
1093 else
1094 res = stringlib_rfind_slice(
1095 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1096 subbuf.buf, subbuf.len, start, end);
Martin v. Löwis423be952008-08-13 15:53:07 +00001097 PyBuffer_Release(&subbuf);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001098 return res;
1099}
1100
1101PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001102"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001103\n\
1104Return the lowest index in B where subsection sub is found,\n\
1105such that sub is contained within s[start,end]. Optional\n\
1106arguments start and end are interpreted as in slice notation.\n\
1107\n\
1108Return -1 on failure.");
1109
1110static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001111bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001112{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001113 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001114 if (result == -2)
1115 return NULL;
1116 return PyLong_FromSsize_t(result);
1117}
1118
1119PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001120"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001121\n\
1122Return the number of non-overlapping occurrences of subsection sub in\n\
1123bytes B[start:end]. Optional arguments start and end are interpreted\n\
1124as in slice notation.");
1125
1126static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001127bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001128{
1129 PyObject *sub_obj;
1130 const char *str = PyByteArray_AS_STRING(self);
1131 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1132 Py_buffer vsub;
1133 PyObject *count_obj;
1134
Jesus Ceaac451502011-04-20 17:09:23 +02001135 if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001136 return NULL;
1137
1138 if (_getbuffer(sub_obj, &vsub) < 0)
1139 return NULL;
1140
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001141 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001142
1143 count_obj = PyLong_FromSsize_t(
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001144 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001145 );
Martin v. Löwis423be952008-08-13 15:53:07 +00001146 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001147 return count_obj;
1148}
1149
1150
1151PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001152"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001153\n\
1154Like B.find() but raise ValueError when the subsection is not found.");
1155
1156static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001157bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001158{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001159 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001160 if (result == -2)
1161 return NULL;
1162 if (result == -1) {
1163 PyErr_SetString(PyExc_ValueError,
1164 "subsection not found");
1165 return NULL;
1166 }
1167 return PyLong_FromSsize_t(result);
1168}
1169
1170
1171PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001172"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001173\n\
1174Return the highest index in B where subsection sub is found,\n\
1175such that sub is contained within s[start,end]. Optional\n\
1176arguments start and end are interpreted as in slice notation.\n\
1177\n\
1178Return -1 on failure.");
1179
1180static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001181bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001182{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001183 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001184 if (result == -2)
1185 return NULL;
1186 return PyLong_FromSsize_t(result);
1187}
1188
1189
1190PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001191"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001192\n\
1193Like B.rfind() but raise ValueError when the subsection is not found.");
1194
1195static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001196bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001197{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001198 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001199 if (result == -2)
1200 return NULL;
1201 if (result == -1) {
1202 PyErr_SetString(PyExc_ValueError,
1203 "subsection not found");
1204 return NULL;
1205 }
1206 return PyLong_FromSsize_t(result);
1207}
1208
1209
1210static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001211bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001212{
1213 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1214 if (ival == -1 && PyErr_Occurred()) {
1215 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001216 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001217 PyErr_Clear();
1218 if (_getbuffer(arg, &varg) < 0)
1219 return -1;
1220 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1221 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001222 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001223 return pos >= 0;
1224 }
1225 if (ival < 0 || ival >= 256) {
1226 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1227 return -1;
1228 }
1229
Antoine Pitrou0010d372010-08-15 17:12:55 +00001230 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001231}
1232
1233
1234/* Matches the end (direction >= 0) or start (direction < 0) of self
1235 * against substr, using the start and end arguments. Returns
1236 * -1 on error, 0 if not found and 1 if found.
1237 */
1238Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001239_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001240 Py_ssize_t end, int direction)
1241{
1242 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1243 const char* str;
1244 Py_buffer vsubstr;
1245 int rv = 0;
1246
1247 str = PyByteArray_AS_STRING(self);
1248
1249 if (_getbuffer(substr, &vsubstr) < 0)
1250 return -1;
1251
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001252 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001253
1254 if (direction < 0) {
1255 /* startswith */
1256 if (start+vsubstr.len > len) {
1257 goto done;
1258 }
1259 } else {
1260 /* endswith */
1261 if (end-start < vsubstr.len || start > len) {
1262 goto done;
1263 }
1264
1265 if (end-vsubstr.len > start)
1266 start = end - vsubstr.len;
1267 }
1268 if (end-start >= vsubstr.len)
1269 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1270
1271done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001272 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001273 return rv;
1274}
1275
1276
1277PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001278"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001279\n\
1280Return True if B starts with the specified prefix, False otherwise.\n\
1281With optional start, test B beginning at that position.\n\
1282With optional end, stop comparing B at that position.\n\
1283prefix can also be a tuple of strings to try.");
1284
1285static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001286bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001287{
1288 Py_ssize_t start = 0;
1289 Py_ssize_t end = PY_SSIZE_T_MAX;
1290 PyObject *subobj;
1291 int result;
1292
Jesus Ceaac451502011-04-20 17:09:23 +02001293 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001294 return NULL;
1295 if (PyTuple_Check(subobj)) {
1296 Py_ssize_t i;
1297 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001298 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001299 PyTuple_GET_ITEM(subobj, i),
1300 start, end, -1);
1301 if (result == -1)
1302 return NULL;
1303 else if (result) {
1304 Py_RETURN_TRUE;
1305 }
1306 }
1307 Py_RETURN_FALSE;
1308 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001309 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001310 if (result == -1)
1311 return NULL;
1312 else
1313 return PyBool_FromLong(result);
1314}
1315
1316PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001317"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001318\n\
1319Return True if B ends with the specified suffix, False otherwise.\n\
1320With optional start, test B beginning at that position.\n\
1321With optional end, stop comparing B at that position.\n\
1322suffix can also be a tuple of strings to try.");
1323
1324static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001325bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001326{
1327 Py_ssize_t start = 0;
1328 Py_ssize_t end = PY_SSIZE_T_MAX;
1329 PyObject *subobj;
1330 int result;
1331
Jesus Ceaac451502011-04-20 17:09:23 +02001332 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001333 return NULL;
1334 if (PyTuple_Check(subobj)) {
1335 Py_ssize_t i;
1336 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001337 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001338 PyTuple_GET_ITEM(subobj, i),
1339 start, end, +1);
1340 if (result == -1)
1341 return NULL;
1342 else if (result) {
1343 Py_RETURN_TRUE;
1344 }
1345 }
1346 Py_RETURN_FALSE;
1347 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001348 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001349 if (result == -1)
1350 return NULL;
1351 else
1352 return PyBool_FromLong(result);
1353}
1354
1355
1356PyDoc_STRVAR(translate__doc__,
1357"B.translate(table[, deletechars]) -> bytearray\n\
1358\n\
1359Return a copy of B, where all characters occurring in the\n\
1360optional argument deletechars are removed, and the remaining\n\
1361characters have been mapped through the given translation\n\
1362table, which must be a bytes object of length 256.");
1363
1364static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001365bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001366{
1367 register char *input, *output;
1368 register const char *table;
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001369 register Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001370 PyObject *input_obj = (PyObject*)self;
1371 const char *output_start;
1372 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001373 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001374 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001375 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001376 Py_buffer vtable, vdel;
1377
1378 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1379 &tableobj, &delobj))
1380 return NULL;
1381
Georg Brandlccc47b62008-12-28 11:44:14 +00001382 if (tableobj == Py_None) {
1383 table = NULL;
1384 tableobj = NULL;
1385 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001386 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001387 } else {
1388 if (vtable.len != 256) {
1389 PyErr_SetString(PyExc_ValueError,
1390 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001391 PyBuffer_Release(&vtable);
1392 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001393 }
1394 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001395 }
1396
1397 if (delobj != NULL) {
1398 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001399 if (tableobj != NULL)
1400 PyBuffer_Release(&vtable);
1401 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001402 }
1403 }
1404 else {
1405 vdel.buf = NULL;
1406 vdel.len = 0;
1407 }
1408
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001409 inlen = PyByteArray_GET_SIZE(input_obj);
1410 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1411 if (result == NULL)
1412 goto done;
1413 output_start = output = PyByteArray_AsString(result);
1414 input = PyByteArray_AS_STRING(input_obj);
1415
Georg Brandlccc47b62008-12-28 11:44:14 +00001416 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001417 /* If no deletions are required, use faster code */
1418 for (i = inlen; --i >= 0; ) {
1419 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001420 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001421 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001422 goto done;
1423 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001424
1425 if (table == NULL) {
1426 for (i = 0; i < 256; i++)
1427 trans_table[i] = Py_CHARMASK(i);
1428 } else {
1429 for (i = 0; i < 256; i++)
1430 trans_table[i] = Py_CHARMASK(table[i]);
1431 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001432
1433 for (i = 0; i < vdel.len; i++)
1434 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1435
1436 for (i = inlen; --i >= 0; ) {
1437 c = Py_CHARMASK(*input++);
1438 if (trans_table[c] != -1)
1439 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1440 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001441 }
1442 /* Fix the size of the resulting string */
1443 if (inlen > 0)
1444 PyByteArray_Resize(result, output - output_start);
1445
1446done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001447 if (tableobj != NULL)
1448 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001449 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001450 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001451 return result;
1452}
1453
1454
Georg Brandlabc38772009-04-12 15:51:51 +00001455static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001456bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001457{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001458 return _Py_bytes_maketrans(args);
Georg Brandlabc38772009-04-12 15:51:51 +00001459}
1460
1461
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001462/* find and count characters and substrings */
1463
1464#define findchar(target, target_len, c) \
1465 ((char *)memchr((const void *)(target), c, target_len))
1466
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001467
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001468/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001469Py_LOCAL(PyByteArrayObject *)
1470return_self(PyByteArrayObject *self)
1471{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001472 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001473 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1474 PyByteArray_AS_STRING(self),
1475 PyByteArray_GET_SIZE(self));
1476}
1477
1478Py_LOCAL_INLINE(Py_ssize_t)
1479countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1480{
1481 Py_ssize_t count=0;
1482 const char *start=target;
1483 const char *end=target+target_len;
1484
1485 while ( (start=findchar(start, end-start, c)) != NULL ) {
1486 count++;
1487 if (count >= maxcount)
1488 break;
1489 start += 1;
1490 }
1491 return count;
1492}
1493
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001494
1495/* Algorithms for different cases of string replacement */
1496
1497/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1498Py_LOCAL(PyByteArrayObject *)
1499replace_interleave(PyByteArrayObject *self,
1500 const char *to_s, Py_ssize_t to_len,
1501 Py_ssize_t maxcount)
1502{
1503 char *self_s, *result_s;
1504 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001505 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001506 PyByteArrayObject *result;
1507
1508 self_len = PyByteArray_GET_SIZE(self);
1509
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001510 /* 1 at the end plus 1 after every character;
1511 count = min(maxcount, self_len + 1) */
1512 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001513 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001514 else
1515 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1516 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001517
1518 /* Check for overflow */
1519 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001520 assert(count > 0);
1521 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001522 PyErr_SetString(PyExc_OverflowError,
1523 "replace string is too long");
1524 return NULL;
1525 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001526 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001527
1528 if (! (result = (PyByteArrayObject *)
1529 PyByteArray_FromStringAndSize(NULL, result_len)) )
1530 return NULL;
1531
1532 self_s = PyByteArray_AS_STRING(self);
1533 result_s = PyByteArray_AS_STRING(result);
1534
1535 /* TODO: special case single character, which doesn't need memcpy */
1536
1537 /* Lay the first one down (guaranteed this will occur) */
1538 Py_MEMCPY(result_s, to_s, to_len);
1539 result_s += to_len;
1540 count -= 1;
1541
1542 for (i=0; i<count; i++) {
1543 *result_s++ = *self_s++;
1544 Py_MEMCPY(result_s, to_s, to_len);
1545 result_s += to_len;
1546 }
1547
1548 /* Copy the rest of the original string */
1549 Py_MEMCPY(result_s, self_s, self_len-i);
1550
1551 return result;
1552}
1553
1554/* Special case for deleting a single character */
1555/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1556Py_LOCAL(PyByteArrayObject *)
1557replace_delete_single_character(PyByteArrayObject *self,
1558 char from_c, Py_ssize_t maxcount)
1559{
1560 char *self_s, *result_s;
1561 char *start, *next, *end;
1562 Py_ssize_t self_len, result_len;
1563 Py_ssize_t count;
1564 PyByteArrayObject *result;
1565
1566 self_len = PyByteArray_GET_SIZE(self);
1567 self_s = PyByteArray_AS_STRING(self);
1568
1569 count = countchar(self_s, self_len, from_c, maxcount);
1570 if (count == 0) {
1571 return return_self(self);
1572 }
1573
1574 result_len = self_len - count; /* from_len == 1 */
1575 assert(result_len>=0);
1576
1577 if ( (result = (PyByteArrayObject *)
1578 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1579 return NULL;
1580 result_s = PyByteArray_AS_STRING(result);
1581
1582 start = self_s;
1583 end = self_s + self_len;
1584 while (count-- > 0) {
1585 next = findchar(start, end-start, from_c);
1586 if (next == NULL)
1587 break;
1588 Py_MEMCPY(result_s, start, next-start);
1589 result_s += (next-start);
1590 start = next+1;
1591 }
1592 Py_MEMCPY(result_s, start, end-start);
1593
1594 return result;
1595}
1596
1597/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1598
1599Py_LOCAL(PyByteArrayObject *)
1600replace_delete_substring(PyByteArrayObject *self,
1601 const char *from_s, Py_ssize_t from_len,
1602 Py_ssize_t maxcount)
1603{
1604 char *self_s, *result_s;
1605 char *start, *next, *end;
1606 Py_ssize_t self_len, result_len;
1607 Py_ssize_t count, offset;
1608 PyByteArrayObject *result;
1609
1610 self_len = PyByteArray_GET_SIZE(self);
1611 self_s = PyByteArray_AS_STRING(self);
1612
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001613 count = stringlib_count(self_s, self_len,
1614 from_s, from_len,
1615 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001616
1617 if (count == 0) {
1618 /* no matches */
1619 return return_self(self);
1620 }
1621
1622 result_len = self_len - (count * from_len);
1623 assert (result_len>=0);
1624
1625 if ( (result = (PyByteArrayObject *)
1626 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1627 return NULL;
1628
1629 result_s = PyByteArray_AS_STRING(result);
1630
1631 start = self_s;
1632 end = self_s + self_len;
1633 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001634 offset = stringlib_find(start, end-start,
1635 from_s, from_len,
1636 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001637 if (offset == -1)
1638 break;
1639 next = start + offset;
1640
1641 Py_MEMCPY(result_s, start, next-start);
1642
1643 result_s += (next-start);
1644 start = next+from_len;
1645 }
1646 Py_MEMCPY(result_s, start, end-start);
1647 return result;
1648}
1649
1650/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1651Py_LOCAL(PyByteArrayObject *)
1652replace_single_character_in_place(PyByteArrayObject *self,
1653 char from_c, char to_c,
1654 Py_ssize_t maxcount)
1655{
Antoine Pitroud1188562010-06-09 16:38:55 +00001656 char *self_s, *result_s, *start, *end, *next;
1657 Py_ssize_t self_len;
1658 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001659
Antoine Pitroud1188562010-06-09 16:38:55 +00001660 /* The result string will be the same size */
1661 self_s = PyByteArray_AS_STRING(self);
1662 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001663
Antoine Pitroud1188562010-06-09 16:38:55 +00001664 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001665
Antoine Pitroud1188562010-06-09 16:38:55 +00001666 if (next == NULL) {
1667 /* No matches; return the original bytes */
1668 return return_self(self);
1669 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001670
Antoine Pitroud1188562010-06-09 16:38:55 +00001671 /* Need to make a new bytes */
1672 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1673 if (result == NULL)
1674 return NULL;
1675 result_s = PyByteArray_AS_STRING(result);
1676 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001677
Antoine Pitroud1188562010-06-09 16:38:55 +00001678 /* change everything in-place, starting with this one */
1679 start = result_s + (next-self_s);
1680 *start = to_c;
1681 start++;
1682 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001683
Antoine Pitroud1188562010-06-09 16:38:55 +00001684 while (--maxcount > 0) {
1685 next = findchar(start, end-start, from_c);
1686 if (next == NULL)
1687 break;
1688 *next = to_c;
1689 start = next+1;
1690 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001691
Antoine Pitroud1188562010-06-09 16:38:55 +00001692 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001693}
1694
1695/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1696Py_LOCAL(PyByteArrayObject *)
1697replace_substring_in_place(PyByteArrayObject *self,
1698 const char *from_s, Py_ssize_t from_len,
1699 const char *to_s, Py_ssize_t to_len,
1700 Py_ssize_t maxcount)
1701{
1702 char *result_s, *start, *end;
1703 char *self_s;
1704 Py_ssize_t self_len, offset;
1705 PyByteArrayObject *result;
1706
1707 /* The result bytes will be the same size */
1708
1709 self_s = PyByteArray_AS_STRING(self);
1710 self_len = PyByteArray_GET_SIZE(self);
1711
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001712 offset = stringlib_find(self_s, self_len,
1713 from_s, from_len,
1714 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001715 if (offset == -1) {
1716 /* No matches; return the original bytes */
1717 return return_self(self);
1718 }
1719
1720 /* Need to make a new bytes */
1721 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1722 if (result == NULL)
1723 return NULL;
1724 result_s = PyByteArray_AS_STRING(result);
1725 Py_MEMCPY(result_s, self_s, self_len);
1726
1727 /* change everything in-place, starting with this one */
1728 start = result_s + offset;
1729 Py_MEMCPY(start, to_s, from_len);
1730 start += from_len;
1731 end = result_s + self_len;
1732
1733 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001734 offset = stringlib_find(start, end-start,
1735 from_s, from_len,
1736 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001737 if (offset==-1)
1738 break;
1739 Py_MEMCPY(start+offset, to_s, from_len);
1740 start += offset+from_len;
1741 }
1742
1743 return result;
1744}
1745
1746/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1747Py_LOCAL(PyByteArrayObject *)
1748replace_single_character(PyByteArrayObject *self,
1749 char from_c,
1750 const char *to_s, Py_ssize_t to_len,
1751 Py_ssize_t maxcount)
1752{
1753 char *self_s, *result_s;
1754 char *start, *next, *end;
1755 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001756 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001757 PyByteArrayObject *result;
1758
1759 self_s = PyByteArray_AS_STRING(self);
1760 self_len = PyByteArray_GET_SIZE(self);
1761
1762 count = countchar(self_s, self_len, from_c, maxcount);
1763 if (count == 0) {
1764 /* no matches, return unchanged */
1765 return return_self(self);
1766 }
1767
1768 /* use the difference between current and new, hence the "-1" */
1769 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001770 assert(count > 0);
1771 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001772 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1773 return NULL;
1774 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001775 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001776
1777 if ( (result = (PyByteArrayObject *)
1778 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1779 return NULL;
1780 result_s = PyByteArray_AS_STRING(result);
1781
1782 start = self_s;
1783 end = self_s + self_len;
1784 while (count-- > 0) {
1785 next = findchar(start, end-start, from_c);
1786 if (next == NULL)
1787 break;
1788
1789 if (next == start) {
1790 /* replace with the 'to' */
1791 Py_MEMCPY(result_s, to_s, to_len);
1792 result_s += to_len;
1793 start += 1;
1794 } else {
1795 /* copy the unchanged old then the 'to' */
1796 Py_MEMCPY(result_s, start, next-start);
1797 result_s += (next-start);
1798 Py_MEMCPY(result_s, to_s, to_len);
1799 result_s += to_len;
1800 start = next+1;
1801 }
1802 }
1803 /* Copy the remainder of the remaining bytes */
1804 Py_MEMCPY(result_s, start, end-start);
1805
1806 return result;
1807}
1808
1809/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1810Py_LOCAL(PyByteArrayObject *)
1811replace_substring(PyByteArrayObject *self,
1812 const char *from_s, Py_ssize_t from_len,
1813 const char *to_s, Py_ssize_t to_len,
1814 Py_ssize_t maxcount)
1815{
1816 char *self_s, *result_s;
1817 char *start, *next, *end;
1818 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001819 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001820 PyByteArrayObject *result;
1821
1822 self_s = PyByteArray_AS_STRING(self);
1823 self_len = PyByteArray_GET_SIZE(self);
1824
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001825 count = stringlib_count(self_s, self_len,
1826 from_s, from_len,
1827 maxcount);
1828
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001829 if (count == 0) {
1830 /* no matches, return unchanged */
1831 return return_self(self);
1832 }
1833
1834 /* Check for overflow */
1835 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001836 assert(count > 0);
1837 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001838 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1839 return NULL;
1840 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001841 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001842
1843 if ( (result = (PyByteArrayObject *)
1844 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1845 return NULL;
1846 result_s = PyByteArray_AS_STRING(result);
1847
1848 start = self_s;
1849 end = self_s + self_len;
1850 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001851 offset = stringlib_find(start, end-start,
1852 from_s, from_len,
1853 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001854 if (offset == -1)
1855 break;
1856 next = start+offset;
1857 if (next == start) {
1858 /* replace with the 'to' */
1859 Py_MEMCPY(result_s, to_s, to_len);
1860 result_s += to_len;
1861 start += from_len;
1862 } else {
1863 /* copy the unchanged old then the 'to' */
1864 Py_MEMCPY(result_s, start, next-start);
1865 result_s += (next-start);
1866 Py_MEMCPY(result_s, to_s, to_len);
1867 result_s += to_len;
1868 start = next+from_len;
1869 }
1870 }
1871 /* Copy the remainder of the remaining bytes */
1872 Py_MEMCPY(result_s, start, end-start);
1873
1874 return result;
1875}
1876
1877
1878Py_LOCAL(PyByteArrayObject *)
1879replace(PyByteArrayObject *self,
1880 const char *from_s, Py_ssize_t from_len,
1881 const char *to_s, Py_ssize_t to_len,
1882 Py_ssize_t maxcount)
1883{
1884 if (maxcount < 0) {
1885 maxcount = PY_SSIZE_T_MAX;
1886 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1887 /* nothing to do; return the original bytes */
1888 return return_self(self);
1889 }
1890
1891 if (maxcount == 0 ||
1892 (from_len == 0 && to_len == 0)) {
1893 /* nothing to do; return the original bytes */
1894 return return_self(self);
1895 }
1896
1897 /* Handle zero-length special cases */
1898
1899 if (from_len == 0) {
1900 /* insert the 'to' bytes everywhere. */
1901 /* >>> "Python".replace("", ".") */
1902 /* '.P.y.t.h.o.n.' */
1903 return replace_interleave(self, to_s, to_len, maxcount);
1904 }
1905
1906 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1907 /* point for an empty self bytes to generate a non-empty bytes */
1908 /* Special case so the remaining code always gets a non-empty bytes */
1909 if (PyByteArray_GET_SIZE(self) == 0) {
1910 return return_self(self);
1911 }
1912
1913 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00001914 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001915 if (from_len == 1) {
1916 return replace_delete_single_character(
1917 self, from_s[0], maxcount);
1918 } else {
1919 return replace_delete_substring(self, from_s, from_len, maxcount);
1920 }
1921 }
1922
1923 /* Handle special case where both bytes have the same length */
1924
1925 if (from_len == to_len) {
1926 if (from_len == 1) {
1927 return replace_single_character_in_place(
1928 self,
1929 from_s[0],
1930 to_s[0],
1931 maxcount);
1932 } else {
1933 return replace_substring_in_place(
1934 self, from_s, from_len, to_s, to_len, maxcount);
1935 }
1936 }
1937
1938 /* Otherwise use the more generic algorithms */
1939 if (from_len == 1) {
1940 return replace_single_character(self, from_s[0],
1941 to_s, to_len, maxcount);
1942 } else {
1943 /* len('from')>=2, len('to')>=1 */
1944 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
1945 }
1946}
1947
1948
1949PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001950"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001951\n\
1952Return a copy of B with all occurrences of subsection\n\
1953old replaced by new. If the optional argument count is\n\
1954given, only the first count occurrences are replaced.");
1955
1956static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001957bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001958{
1959 Py_ssize_t count = -1;
1960 PyObject *from, *to, *res;
1961 Py_buffer vfrom, vto;
1962
1963 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
1964 return NULL;
1965
1966 if (_getbuffer(from, &vfrom) < 0)
1967 return NULL;
1968 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +00001969 PyBuffer_Release(&vfrom);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001970 return NULL;
1971 }
1972
1973 res = (PyObject *)replace((PyByteArrayObject *) self,
1974 vfrom.buf, vfrom.len,
1975 vto.buf, vto.len, count);
1976
Martin v. Löwis423be952008-08-13 15:53:07 +00001977 PyBuffer_Release(&vfrom);
1978 PyBuffer_Release(&vto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001979 return res;
1980}
1981
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001982PyDoc_STRVAR(split__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001983"B.split([sep[, maxsplit]]) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001984\n\
1985Return a list of the sections in B, using sep as the delimiter.\n\
1986If sep is not given, B is split on ASCII whitespace characters\n\
1987(space, tab, return, newline, formfeed, vertical tab).\n\
1988If maxsplit is given, at most maxsplit splits are done.");
1989
1990static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001991bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001992{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001993 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1994 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001995 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001996 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001997 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001998
1999 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2000 return NULL;
2001 if (maxsplit < 0)
2002 maxsplit = PY_SSIZE_T_MAX;
2003
2004 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002005 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002006
2007 if (_getbuffer(subobj, &vsub) < 0)
2008 return NULL;
2009 sub = vsub.buf;
2010 n = vsub.len;
2011
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002012 list = stringlib_split(
2013 (PyObject*) self, s, len, sub, n, maxsplit
2014 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002015 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002016 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002017}
2018
2019PyDoc_STRVAR(partition__doc__,
2020"B.partition(sep) -> (head, sep, tail)\n\
2021\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002022Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002023the separator itself, and the part after it. If the separator is not\n\
2024found, returns B and two empty bytearray objects.");
2025
2026static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002027bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002028{
2029 PyObject *bytesep, *result;
2030
2031 bytesep = PyByteArray_FromObject(sep_obj);
2032 if (! bytesep)
2033 return NULL;
2034
2035 result = stringlib_partition(
2036 (PyObject*) self,
2037 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2038 bytesep,
2039 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2040 );
2041
2042 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002043 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002044}
2045
2046PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002047"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002048\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002049Search for the separator sep in B, starting at the end of B,\n\
2050and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002051part after it. If the separator is not found, returns two empty\n\
2052bytearray objects and B.");
2053
2054static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002055bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002056{
2057 PyObject *bytesep, *result;
2058
2059 bytesep = PyByteArray_FromObject(sep_obj);
2060 if (! bytesep)
2061 return NULL;
2062
2063 result = stringlib_rpartition(
2064 (PyObject*) self,
2065 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2066 bytesep,
2067 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2068 );
2069
2070 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002071 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002072}
2073
2074PyDoc_STRVAR(rsplit__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002075"B.rsplit(sep[, maxsplit]) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002076\n\
2077Return a list of the sections in B, using sep as the delimiter,\n\
2078starting at the end of B and working to the front.\n\
2079If sep is not given, B is split on ASCII whitespace characters\n\
2080(space, tab, return, newline, formfeed, vertical tab).\n\
2081If maxsplit is given, at most maxsplit splits are done.");
2082
2083static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002084bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002085{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002086 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2087 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002088 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002089 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002090 Py_buffer vsub;
2091
2092 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2093 return NULL;
2094 if (maxsplit < 0)
2095 maxsplit = PY_SSIZE_T_MAX;
2096
2097 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002098 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002099
2100 if (_getbuffer(subobj, &vsub) < 0)
2101 return NULL;
2102 sub = vsub.buf;
2103 n = vsub.len;
2104
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002105 list = stringlib_rsplit(
2106 (PyObject*) self, s, len, sub, n, maxsplit
2107 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002108 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002109 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002110}
2111
2112PyDoc_STRVAR(reverse__doc__,
2113"B.reverse() -> None\n\
2114\n\
2115Reverse the order of the values in B in place.");
2116static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002117bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002118{
2119 char swap, *head, *tail;
2120 Py_ssize_t i, j, n = Py_SIZE(self);
2121
2122 j = n / 2;
2123 head = self->ob_bytes;
2124 tail = head + n - 1;
2125 for (i = 0; i < j; i++) {
2126 swap = *head;
2127 *head++ = *tail;
2128 *tail-- = swap;
2129 }
2130
2131 Py_RETURN_NONE;
2132}
2133
2134PyDoc_STRVAR(insert__doc__,
2135"B.insert(index, int) -> None\n\
2136\n\
2137Insert a single item into the bytearray before the given index.");
2138static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002139bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002140{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002141 PyObject *value;
2142 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002143 Py_ssize_t where, n = Py_SIZE(self);
2144
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002145 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002146 return NULL;
2147
2148 if (n == PY_SSIZE_T_MAX) {
2149 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002150 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002151 return NULL;
2152 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002153 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002154 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002155 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2156 return NULL;
2157
2158 if (where < 0) {
2159 where += n;
2160 if (where < 0)
2161 where = 0;
2162 }
2163 if (where > n)
2164 where = n;
2165 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002166 self->ob_bytes[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002167
2168 Py_RETURN_NONE;
2169}
2170
2171PyDoc_STRVAR(append__doc__,
2172"B.append(int) -> None\n\
2173\n\
2174Append a single item to the end of B.");
2175static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002176bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002177{
2178 int value;
2179 Py_ssize_t n = Py_SIZE(self);
2180
2181 if (! _getbytevalue(arg, &value))
2182 return NULL;
2183 if (n == PY_SSIZE_T_MAX) {
2184 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002185 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002186 return NULL;
2187 }
2188 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2189 return NULL;
2190
2191 self->ob_bytes[n] = value;
2192
2193 Py_RETURN_NONE;
2194}
2195
2196PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002197"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002198\n\
2199Append all the elements from the iterator or sequence to the\n\
2200end of B.");
2201static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002202bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002203{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002204 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002205 Py_ssize_t buf_size = 0, len = 0;
2206 int value;
2207 char *buf;
2208
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002209 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002210 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002211 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002212 return NULL;
2213
2214 Py_RETURN_NONE;
2215 }
2216
2217 it = PyObject_GetIter(arg);
2218 if (it == NULL)
2219 return NULL;
2220
Ezio Melotti42da6632011-03-15 05:18:48 +02002221 /* Try to determine the length of the argument. 32 is arbitrary. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002222 buf_size = _PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002223 if (buf_size == -1) {
2224 Py_DECREF(it);
2225 return NULL;
2226 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002227
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002228 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2229 if (bytearray_obj == NULL)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002230 return NULL;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002231 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002232
2233 while ((item = PyIter_Next(it)) != NULL) {
2234 if (! _getbytevalue(item, &value)) {
2235 Py_DECREF(item);
2236 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002237 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002238 return NULL;
2239 }
2240 buf[len++] = value;
2241 Py_DECREF(item);
2242
2243 if (len >= buf_size) {
2244 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002245 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002246 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002247 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002248 return NULL;
2249 }
2250 /* Recompute the `buf' pointer, since the resizing operation may
2251 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002252 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002253 }
2254 }
2255 Py_DECREF(it);
2256
2257 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002258 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2259 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002260 return NULL;
2261 }
2262
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002263 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002264 return NULL;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002265 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002266
2267 Py_RETURN_NONE;
2268}
2269
2270PyDoc_STRVAR(pop__doc__,
2271"B.pop([index]) -> int\n\
2272\n\
2273Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002274argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002275static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002276bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002277{
2278 int value;
2279 Py_ssize_t where = -1, n = Py_SIZE(self);
2280
2281 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2282 return NULL;
2283
2284 if (n == 0) {
Eli Benderskye0c86352011-03-04 05:10:57 +00002285 PyErr_SetString(PyExc_IndexError,
2286 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002287 return NULL;
2288 }
2289 if (where < 0)
2290 where += Py_SIZE(self);
2291 if (where < 0 || where >= Py_SIZE(self)) {
2292 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2293 return NULL;
2294 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002295 if (!_canresize(self))
2296 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002297
2298 value = self->ob_bytes[where];
2299 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2300 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2301 return NULL;
2302
Mark Dickinson54a3db92009-09-06 10:19:23 +00002303 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002304}
2305
2306PyDoc_STRVAR(remove__doc__,
2307"B.remove(int) -> None\n\
2308\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002309Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002310static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002311bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002312{
2313 int value;
2314 Py_ssize_t where, n = Py_SIZE(self);
2315
2316 if (! _getbytevalue(arg, &value))
2317 return NULL;
2318
2319 for (where = 0; where < n; where++) {
2320 if (self->ob_bytes[where] == value)
2321 break;
2322 }
2323 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002324 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002325 return NULL;
2326 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002327 if (!_canresize(self))
2328 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002329
2330 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2331 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2332 return NULL;
2333
2334 Py_RETURN_NONE;
2335}
2336
2337/* XXX These two helpers could be optimized if argsize == 1 */
2338
2339static Py_ssize_t
2340lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2341 void *argptr, Py_ssize_t argsize)
2342{
2343 Py_ssize_t i = 0;
2344 while (i < mysize && memchr(argptr, myptr[i], argsize))
2345 i++;
2346 return i;
2347}
2348
2349static Py_ssize_t
2350rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2351 void *argptr, Py_ssize_t argsize)
2352{
2353 Py_ssize_t i = mysize - 1;
2354 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2355 i--;
2356 return i + 1;
2357}
2358
2359PyDoc_STRVAR(strip__doc__,
2360"B.strip([bytes]) -> bytearray\n\
2361\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002362Strip leading and trailing bytes contained in the argument\n\
2363and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002364If the argument is omitted, strip ASCII whitespace.");
2365static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002366bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002367{
2368 Py_ssize_t left, right, mysize, argsize;
2369 void *myptr, *argptr;
2370 PyObject *arg = Py_None;
2371 Py_buffer varg;
2372 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2373 return NULL;
2374 if (arg == Py_None) {
2375 argptr = "\t\n\r\f\v ";
2376 argsize = 6;
2377 }
2378 else {
2379 if (_getbuffer(arg, &varg) < 0)
2380 return NULL;
2381 argptr = varg.buf;
2382 argsize = varg.len;
2383 }
2384 myptr = self->ob_bytes;
2385 mysize = Py_SIZE(self);
2386 left = lstrip_helper(myptr, mysize, argptr, argsize);
2387 if (left == mysize)
2388 right = left;
2389 else
2390 right = rstrip_helper(myptr, mysize, argptr, argsize);
2391 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002392 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002393 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2394}
2395
2396PyDoc_STRVAR(lstrip__doc__,
2397"B.lstrip([bytes]) -> bytearray\n\
2398\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002399Strip leading bytes contained in the argument\n\
2400and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002401If the argument is omitted, strip leading ASCII whitespace.");
2402static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002403bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002404{
2405 Py_ssize_t left, right, mysize, argsize;
2406 void *myptr, *argptr;
2407 PyObject *arg = Py_None;
2408 Py_buffer varg;
2409 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2410 return NULL;
2411 if (arg == Py_None) {
2412 argptr = "\t\n\r\f\v ";
2413 argsize = 6;
2414 }
2415 else {
2416 if (_getbuffer(arg, &varg) < 0)
2417 return NULL;
2418 argptr = varg.buf;
2419 argsize = varg.len;
2420 }
2421 myptr = self->ob_bytes;
2422 mysize = Py_SIZE(self);
2423 left = lstrip_helper(myptr, mysize, argptr, argsize);
2424 right = mysize;
2425 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002426 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002427 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2428}
2429
2430PyDoc_STRVAR(rstrip__doc__,
2431"B.rstrip([bytes]) -> bytearray\n\
2432\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002433Strip trailing bytes contained in the argument\n\
2434and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002435If the argument is omitted, strip trailing ASCII whitespace.");
2436static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002437bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002438{
2439 Py_ssize_t left, right, mysize, argsize;
2440 void *myptr, *argptr;
2441 PyObject *arg = Py_None;
2442 Py_buffer varg;
2443 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2444 return NULL;
2445 if (arg == Py_None) {
2446 argptr = "\t\n\r\f\v ";
2447 argsize = 6;
2448 }
2449 else {
2450 if (_getbuffer(arg, &varg) < 0)
2451 return NULL;
2452 argptr = varg.buf;
2453 argsize = varg.len;
2454 }
2455 myptr = self->ob_bytes;
2456 mysize = Py_SIZE(self);
2457 left = 0;
2458 right = rstrip_helper(myptr, mysize, argptr, argsize);
2459 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002460 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002461 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2462}
2463
2464PyDoc_STRVAR(decode_doc,
Victor Stinnerc911bbf2010-11-07 19:04:46 +00002465"B.decode(encoding='utf-8', errors='strict') -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002466\n\
Victor Stinnere14e2122010-11-07 18:41:46 +00002467Decode B using the codec registered for encoding. Default encoding\n\
2468is 'utf-8'. errors may be given to set a different error\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002469handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2470a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2471as well as any other name registered with codecs.register_error that is\n\
2472able to handle UnicodeDecodeErrors.");
2473
2474static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002475bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002476{
2477 const char *encoding = NULL;
2478 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002479 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002480
Benjamin Peterson308d6372009-09-18 21:42:35 +00002481 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002482 return NULL;
2483 if (encoding == NULL)
2484 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002485 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002486}
2487
2488PyDoc_STRVAR(alloc_doc,
2489"B.__alloc__() -> int\n\
2490\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002491Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002492
2493static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002494bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002495{
2496 return PyLong_FromSsize_t(self->ob_alloc);
2497}
2498
2499PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002500"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002501\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002502Concatenate any number of bytes/bytearray objects, with B\n\
2503in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002504
2505static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002506bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002507{
2508 PyObject *seq;
2509 Py_ssize_t mysize = Py_SIZE(self);
2510 Py_ssize_t i;
2511 Py_ssize_t n;
2512 PyObject **items;
2513 Py_ssize_t totalsize = 0;
2514 PyObject *result;
2515 char *dest;
2516
2517 seq = PySequence_Fast(it, "can only join an iterable");
2518 if (seq == NULL)
2519 return NULL;
2520 n = PySequence_Fast_GET_SIZE(seq);
2521 items = PySequence_Fast_ITEMS(seq);
2522
2523 /* Compute the total size, and check that they are all bytes */
2524 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2525 for (i = 0; i < n; i++) {
2526 PyObject *obj = items[i];
2527 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2528 PyErr_Format(PyExc_TypeError,
2529 "can only join an iterable of bytes "
2530 "(item %ld has type '%.100s')",
2531 /* XXX %ld isn't right on Win64 */
2532 (long)i, Py_TYPE(obj)->tp_name);
2533 goto error;
2534 }
2535 if (i > 0)
2536 totalsize += mysize;
2537 totalsize += Py_SIZE(obj);
2538 if (totalsize < 0) {
2539 PyErr_NoMemory();
2540 goto error;
2541 }
2542 }
2543
2544 /* Allocate the result, and copy the bytes */
2545 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2546 if (result == NULL)
2547 goto error;
2548 dest = PyByteArray_AS_STRING(result);
2549 for (i = 0; i < n; i++) {
2550 PyObject *obj = items[i];
2551 Py_ssize_t size = Py_SIZE(obj);
2552 char *buf;
2553 if (PyByteArray_Check(obj))
2554 buf = PyByteArray_AS_STRING(obj);
2555 else
2556 buf = PyBytes_AS_STRING(obj);
2557 if (i) {
2558 memcpy(dest, self->ob_bytes, mysize);
2559 dest += mysize;
2560 }
2561 memcpy(dest, buf, size);
2562 dest += size;
2563 }
2564
2565 /* Done */
2566 Py_DECREF(seq);
2567 return result;
2568
2569 /* Error handling */
2570 error:
2571 Py_DECREF(seq);
2572 return NULL;
2573}
2574
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002575PyDoc_STRVAR(splitlines__doc__,
2576"B.splitlines([keepends]) -> list of lines\n\
2577\n\
2578Return a list of the lines in B, breaking at line boundaries.\n\
2579Line breaks are not included in the resulting list unless keepends\n\
2580is given and true.");
2581
2582static PyObject*
2583bytearray_splitlines(PyObject *self, PyObject *args)
2584{
2585 int keepends = 0;
2586
2587 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2588 return NULL;
2589
2590 return stringlib_splitlines(
2591 (PyObject*) self, PyByteArray_AS_STRING(self),
2592 PyByteArray_GET_SIZE(self), keepends
2593 );
2594}
2595
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002596PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002597"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002598\n\
2599Create a bytearray object from a string of hexadecimal numbers.\n\
2600Spaces between two numbers are accepted.\n\
2601Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2602
2603static int
2604hex_digit_to_int(Py_UNICODE c)
2605{
2606 if (c >= 128)
2607 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002608 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002609 return c - '0';
2610 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002611 if (Py_ISUPPER(c))
2612 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002613 if (c >= 'a' && c <= 'f')
2614 return c - 'a' + 10;
2615 }
2616 return -1;
2617}
2618
2619static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002620bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002621{
2622 PyObject *newbytes, *hexobj;
2623 char *buf;
2624 Py_UNICODE *hex;
2625 Py_ssize_t hexlen, byteslen, i, j;
2626 int top, bot;
2627
2628 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2629 return NULL;
2630 assert(PyUnicode_Check(hexobj));
2631 hexlen = PyUnicode_GET_SIZE(hexobj);
2632 hex = PyUnicode_AS_UNICODE(hexobj);
2633 byteslen = hexlen/2; /* This overestimates if there are spaces */
2634 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2635 if (!newbytes)
2636 return NULL;
2637 buf = PyByteArray_AS_STRING(newbytes);
2638 for (i = j = 0; i < hexlen; i += 2) {
2639 /* skip over spaces in the input */
2640 while (hex[i] == ' ')
2641 i++;
2642 if (i >= hexlen)
2643 break;
2644 top = hex_digit_to_int(hex[i]);
2645 bot = hex_digit_to_int(hex[i+1]);
2646 if (top == -1 || bot == -1) {
2647 PyErr_Format(PyExc_ValueError,
2648 "non-hexadecimal number found in "
2649 "fromhex() arg at position %zd", i);
2650 goto error;
2651 }
2652 buf[j++] = (top << 4) + bot;
2653 }
2654 if (PyByteArray_Resize(newbytes, j) < 0)
2655 goto error;
2656 return newbytes;
2657
2658 error:
2659 Py_DECREF(newbytes);
2660 return NULL;
2661}
2662
2663PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2664
2665static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002666bytearray_reduce(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002667{
2668 PyObject *latin1, *dict;
2669 if (self->ob_bytes)
2670 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2671 Py_SIZE(self), NULL);
2672 else
2673 latin1 = PyUnicode_FromString("");
2674
2675 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2676 if (dict == NULL) {
2677 PyErr_Clear();
2678 dict = Py_None;
2679 Py_INCREF(dict);
2680 }
2681
2682 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2683}
2684
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002685PyDoc_STRVAR(sizeof_doc,
2686"B.__sizeof__() -> int\n\
2687 \n\
2688Returns the size of B in memory, in bytes");
2689static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002690bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002691{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002692 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002693
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002694 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2695 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002696}
2697
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002698static PySequenceMethods bytearray_as_sequence = {
2699 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002700 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002701 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2702 (ssizeargfunc)bytearray_getitem, /* sq_item */
2703 0, /* sq_slice */
2704 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2705 0, /* sq_ass_slice */
2706 (objobjproc)bytearray_contains, /* sq_contains */
2707 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2708 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002709};
2710
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002711static PyMappingMethods bytearray_as_mapping = {
2712 (lenfunc)bytearray_length,
2713 (binaryfunc)bytearray_subscript,
2714 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002715};
2716
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002717static PyBufferProcs bytearray_as_buffer = {
2718 (getbufferproc)bytearray_getbuffer,
2719 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002720};
2721
2722static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002723bytearray_methods[] = {
2724 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2725 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2726 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2727 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002728 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2729 _Py_capitalize__doc__},
2730 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002731 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002732 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002733 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002734 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2735 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002736 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2737 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2738 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002739 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002740 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2741 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002742 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2743 _Py_isalnum__doc__},
2744 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2745 _Py_isalpha__doc__},
2746 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2747 _Py_isdigit__doc__},
2748 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2749 _Py_islower__doc__},
2750 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2751 _Py_isspace__doc__},
2752 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2753 _Py_istitle__doc__},
2754 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2755 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002756 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002757 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2758 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002759 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2760 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002761 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002762 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2763 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2764 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2765 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2766 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2767 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2768 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002769 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002770 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2771 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2772 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2773 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002774 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002775 splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002776 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002777 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002778 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002779 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2780 _Py_swapcase__doc__},
2781 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002782 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002783 translate__doc__},
2784 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2785 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2786 {NULL}
2787};
2788
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002789PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002790"bytearray(iterable_of_ints) -> bytearray\n\
2791bytearray(string, encoding[, errors]) -> bytearray\n\
2792bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray\n\
2793bytearray(memory_view) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002794\n\
2795Construct an mutable bytearray object from:\n\
2796 - an iterable yielding integers in range(256)\n\
2797 - a text string encoded using the specified encoding\n\
2798 - a bytes or a bytearray object\n\
2799 - any object implementing the buffer API.\n\
2800\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002801bytearray(int) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002802\n\
2803Construct a zero-initialized bytearray of the given length.");
2804
2805
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002806static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002807
2808PyTypeObject PyByteArray_Type = {
2809 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2810 "bytearray",
2811 sizeof(PyByteArrayObject),
2812 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002813 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002814 0, /* tp_print */
2815 0, /* tp_getattr */
2816 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002817 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002818 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002819 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002820 &bytearray_as_sequence, /* tp_as_sequence */
2821 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002822 0, /* tp_hash */
2823 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002824 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002825 PyObject_GenericGetAttr, /* tp_getattro */
2826 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002827 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002828 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002829 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002830 0, /* tp_traverse */
2831 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002832 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002833 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002834 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002835 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002836 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002837 0, /* tp_members */
2838 0, /* tp_getset */
2839 0, /* tp_base */
2840 0, /* tp_dict */
2841 0, /* tp_descr_get */
2842 0, /* tp_descr_set */
2843 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002844 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002845 PyType_GenericAlloc, /* tp_alloc */
2846 PyType_GenericNew, /* tp_new */
2847 PyObject_Del, /* tp_free */
2848};
2849
2850/*********************** Bytes Iterator ****************************/
2851
2852typedef struct {
2853 PyObject_HEAD
2854 Py_ssize_t it_index;
2855 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2856} bytesiterobject;
2857
2858static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002859bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002860{
2861 _PyObject_GC_UNTRACK(it);
2862 Py_XDECREF(it->it_seq);
2863 PyObject_GC_Del(it);
2864}
2865
2866static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002867bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002868{
2869 Py_VISIT(it->it_seq);
2870 return 0;
2871}
2872
2873static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002874bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002875{
2876 PyByteArrayObject *seq;
2877 PyObject *item;
2878
2879 assert(it != NULL);
2880 seq = it->it_seq;
2881 if (seq == NULL)
2882 return NULL;
2883 assert(PyByteArray_Check(seq));
2884
2885 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2886 item = PyLong_FromLong(
2887 (unsigned char)seq->ob_bytes[it->it_index]);
2888 if (item != NULL)
2889 ++it->it_index;
2890 return item;
2891 }
2892
2893 Py_DECREF(seq);
2894 it->it_seq = NULL;
2895 return NULL;
2896}
2897
2898static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002899bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002900{
2901 Py_ssize_t len = 0;
2902 if (it->it_seq)
2903 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2904 return PyLong_FromSsize_t(len);
2905}
2906
2907PyDoc_STRVAR(length_hint_doc,
2908 "Private method returning an estimate of len(list(it)).");
2909
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002910static PyMethodDef bytearrayiter_methods[] = {
2911 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002912 length_hint_doc},
2913 {NULL, NULL} /* sentinel */
2914};
2915
2916PyTypeObject PyByteArrayIter_Type = {
2917 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2918 "bytearray_iterator", /* tp_name */
2919 sizeof(bytesiterobject), /* tp_basicsize */
2920 0, /* tp_itemsize */
2921 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002922 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002923 0, /* tp_print */
2924 0, /* tp_getattr */
2925 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002926 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002927 0, /* tp_repr */
2928 0, /* tp_as_number */
2929 0, /* tp_as_sequence */
2930 0, /* tp_as_mapping */
2931 0, /* tp_hash */
2932 0, /* tp_call */
2933 0, /* tp_str */
2934 PyObject_GenericGetAttr, /* tp_getattro */
2935 0, /* tp_setattro */
2936 0, /* tp_as_buffer */
2937 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2938 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002939 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002940 0, /* tp_clear */
2941 0, /* tp_richcompare */
2942 0, /* tp_weaklistoffset */
2943 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002944 (iternextfunc)bytearrayiter_next, /* tp_iternext */
2945 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002946 0,
2947};
2948
2949static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002950bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002951{
2952 bytesiterobject *it;
2953
2954 if (!PyByteArray_Check(seq)) {
2955 PyErr_BadInternalCall();
2956 return NULL;
2957 }
2958 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
2959 if (it == NULL)
2960 return NULL;
2961 it->it_index = 0;
2962 Py_INCREF(seq);
2963 it->it_seq = (PyByteArrayObject *)seq;
2964 _PyObject_GC_TRACK(it);
2965 return (PyObject *)it;
2966}