blob: 4d32ea70f3d5b8cb99ac2eb030d3ac7c651f670b [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");
Christian Heimes2c9c7a52008-05-26 13:42:13 +000036 return 0;
37 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +000038 face_value = PyLong_AsLong(index);
39 Py_DECREF(index);
40 }
41
42 if (face_value < 0 || face_value >= 256) {
43 /* this includes the OverflowError in case the long is too large */
44 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Christian Heimes2c9c7a52008-05-26 13:42:13 +000045 return 0;
46 }
47
48 *value = face_value;
49 return 1;
50}
51
52static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +000053bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000054{
55 int ret;
56 void *ptr;
57 if (view == NULL) {
58 obj->ob_exports++;
59 return 0;
60 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000061 ptr = (void *) PyByteArray_AS_STRING(obj);
Martin v. Löwis423be952008-08-13 15:53:07 +000062 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
Christian Heimes2c9c7a52008-05-26 13:42:13 +000063 if (ret >= 0) {
64 obj->ob_exports++;
65 }
66 return ret;
67}
68
69static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +000070bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000071{
72 obj->ob_exports--;
73}
74
75static Py_ssize_t
76_getbuffer(PyObject *obj, Py_buffer *view)
77{
78 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
79
80 if (buffer == NULL || buffer->bf_getbuffer == NULL)
81 {
82 PyErr_Format(PyExc_TypeError,
83 "Type %.100s doesn't support the buffer API",
84 Py_TYPE(obj)->tp_name);
85 return -1;
86 }
87
88 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
89 return -1;
90 return view->len;
91}
92
Antoine Pitrou5504e892008-12-06 21:27:53 +000093static int
94_canresize(PyByteArrayObject *self)
95{
96 if (self->ob_exports > 0) {
97 PyErr_SetString(PyExc_BufferError,
98 "Existing exports of data: object cannot be re-sized");
99 return 0;
100 }
101 return 1;
102}
103
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000104/* Direct API functions */
105
106PyObject *
107PyByteArray_FromObject(PyObject *input)
108{
109 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
110 input, NULL);
111}
112
113PyObject *
114PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
115{
116 PyByteArrayObject *new;
117 Py_ssize_t alloc;
118
119 if (size < 0) {
120 PyErr_SetString(PyExc_SystemError,
121 "Negative size passed to PyByteArray_FromStringAndSize");
122 return NULL;
123 }
124
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000125 /* Prevent buffer overflow when setting alloc to size+1. */
126 if (size == PY_SSIZE_T_MAX) {
127 return PyErr_NoMemory();
128 }
129
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000130 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
131 if (new == NULL)
132 return NULL;
133
134 if (size == 0) {
135 new->ob_bytes = NULL;
136 alloc = 0;
137 }
138 else {
139 alloc = size + 1;
140 new->ob_bytes = PyMem_Malloc(alloc);
141 if (new->ob_bytes == NULL) {
142 Py_DECREF(new);
143 return PyErr_NoMemory();
144 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +0000145 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000146 memcpy(new->ob_bytes, bytes, size);
147 new->ob_bytes[size] = '\0'; /* Trailing null byte */
148 }
149 Py_SIZE(new) = size;
150 new->ob_alloc = alloc;
151 new->ob_exports = 0;
152
153 return (PyObject *)new;
154}
155
156Py_ssize_t
157PyByteArray_Size(PyObject *self)
158{
159 assert(self != NULL);
160 assert(PyByteArray_Check(self));
161
162 return PyByteArray_GET_SIZE(self);
163}
164
165char *
166PyByteArray_AsString(PyObject *self)
167{
168 assert(self != NULL);
169 assert(PyByteArray_Check(self));
170
171 return PyByteArray_AS_STRING(self);
172}
173
174int
175PyByteArray_Resize(PyObject *self, Py_ssize_t size)
176{
177 void *sval;
178 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
179
180 assert(self != NULL);
181 assert(PyByteArray_Check(self));
182 assert(size >= 0);
183
Antoine Pitrou5504e892008-12-06 21:27:53 +0000184 if (size == Py_SIZE(self)) {
185 return 0;
186 }
187 if (!_canresize((PyByteArrayObject *)self)) {
188 return -1;
189 }
190
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000191 if (size < alloc / 2) {
192 /* Major downsize; resize down to exact size */
193 alloc = size + 1;
194 }
195 else if (size < alloc) {
196 /* Within allocated size; quick exit */
197 Py_SIZE(self) = size;
198 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
199 return 0;
200 }
201 else if (size <= alloc * 1.125) {
202 /* Moderate upsize; overallocate similar to list_resize() */
203 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
204 }
205 else {
206 /* Major upsize; resize up to exact size */
207 alloc = size + 1;
208 }
209
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000210 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
211 if (sval == NULL) {
212 PyErr_NoMemory();
213 return -1;
214 }
215
216 ((PyByteArrayObject *)self)->ob_bytes = sval;
217 Py_SIZE(self) = size;
218 ((PyByteArrayObject *)self)->ob_alloc = alloc;
219 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
220
221 return 0;
222}
223
224PyObject *
225PyByteArray_Concat(PyObject *a, PyObject *b)
226{
227 Py_ssize_t size;
228 Py_buffer va, vb;
229 PyByteArrayObject *result = NULL;
230
231 va.len = -1;
232 vb.len = -1;
233 if (_getbuffer(a, &va) < 0 ||
234 _getbuffer(b, &vb) < 0) {
235 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
236 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
237 goto done;
238 }
239
240 size = va.len + vb.len;
241 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000242 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000243 goto done;
244 }
245
246 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
247 if (result != NULL) {
248 memcpy(result->ob_bytes, va.buf, va.len);
249 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
250 }
251
252 done:
253 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000254 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000255 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000256 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000257 return (PyObject *)result;
258}
259
260/* Functions stuffed into the type object */
261
262static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000263bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000264{
265 return Py_SIZE(self);
266}
267
268static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000269bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000270{
271 Py_ssize_t mysize;
272 Py_ssize_t size;
273 Py_buffer vo;
274
275 if (_getbuffer(other, &vo) < 0) {
276 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
277 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
278 return NULL;
279 }
280
281 mysize = Py_SIZE(self);
282 size = mysize + vo.len;
283 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000284 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000285 return PyErr_NoMemory();
286 }
287 if (size < self->ob_alloc) {
288 Py_SIZE(self) = size;
289 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
290 }
291 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000292 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000293 return NULL;
294 }
295 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000296 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000297 Py_INCREF(self);
298 return (PyObject *)self;
299}
300
301static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000302bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000303{
304 PyByteArrayObject *result;
305 Py_ssize_t mysize;
306 Py_ssize_t size;
307
308 if (count < 0)
309 count = 0;
310 mysize = Py_SIZE(self);
311 size = mysize * count;
312 if (count != 0 && size / count != mysize)
313 return PyErr_NoMemory();
314 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
315 if (result != NULL && size != 0) {
316 if (mysize == 1)
317 memset(result->ob_bytes, self->ob_bytes[0], size);
318 else {
319 Py_ssize_t i;
320 for (i = 0; i < count; i++)
321 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
322 }
323 }
324 return (PyObject *)result;
325}
326
327static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000328bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000329{
330 Py_ssize_t mysize;
331 Py_ssize_t size;
332
333 if (count < 0)
334 count = 0;
335 mysize = Py_SIZE(self);
336 size = mysize * count;
337 if (count != 0 && size / count != mysize)
338 return PyErr_NoMemory();
339 if (size < self->ob_alloc) {
340 Py_SIZE(self) = size;
341 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
342 }
343 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
344 return NULL;
345
346 if (mysize == 1)
347 memset(self->ob_bytes, self->ob_bytes[0], size);
348 else {
349 Py_ssize_t i;
350 for (i = 1; i < count; i++)
351 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
352 }
353
354 Py_INCREF(self);
355 return (PyObject *)self;
356}
357
358static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000359bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000360{
361 if (i < 0)
362 i += Py_SIZE(self);
363 if (i < 0 || i >= Py_SIZE(self)) {
364 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
365 return NULL;
366 }
367 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
368}
369
370static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000371bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000372{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000373 if (PyIndex_Check(index)) {
374 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000375
376 if (i == -1 && PyErr_Occurred())
377 return NULL;
378
379 if (i < 0)
380 i += PyByteArray_GET_SIZE(self);
381
382 if (i < 0 || i >= Py_SIZE(self)) {
383 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
384 return NULL;
385 }
386 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
387 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000388 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000389 Py_ssize_t start, stop, step, slicelength, cur, i;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000390 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000391 PyByteArray_GET_SIZE(self),
392 &start, &stop, &step, &slicelength) < 0) {
393 return NULL;
394 }
395
396 if (slicelength <= 0)
397 return PyByteArray_FromStringAndSize("", 0);
398 else if (step == 1) {
399 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
400 slicelength);
401 }
402 else {
403 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000404 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000405 PyObject *result;
406
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000407 result = PyByteArray_FromStringAndSize(NULL, slicelength);
408 if (result == NULL)
409 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000410
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000411 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000412 for (cur = start, i = 0; i < slicelength;
413 cur += step, i++) {
414 result_buf[i] = source_buf[cur];
415 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000416 return result;
417 }
418 }
419 else {
420 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
421 return NULL;
422 }
423}
424
425static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000426bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000427 PyObject *values)
428{
429 Py_ssize_t avail, needed;
430 void *bytes;
431 Py_buffer vbytes;
432 int res = 0;
433
434 vbytes.len = -1;
435 if (values == (PyObject *)self) {
436 /* Make a copy and call this function recursively */
437 int err;
438 values = PyByteArray_FromObject(values);
439 if (values == NULL)
440 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000441 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000442 Py_DECREF(values);
443 return err;
444 }
445 if (values == NULL) {
446 /* del b[lo:hi] */
447 bytes = NULL;
448 needed = 0;
449 }
450 else {
451 if (_getbuffer(values, &vbytes) < 0) {
452 PyErr_Format(PyExc_TypeError,
Georg Brandl3dbca812008-07-23 16:10:53 +0000453 "can't set bytearray slice from %.100s",
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000454 Py_TYPE(values)->tp_name);
455 return -1;
456 }
457 needed = vbytes.len;
458 bytes = vbytes.buf;
459 }
460
461 if (lo < 0)
462 lo = 0;
463 if (hi < lo)
464 hi = lo;
465 if (hi > Py_SIZE(self))
466 hi = Py_SIZE(self);
467
468 avail = hi - lo;
469 if (avail < 0)
470 lo = hi = avail = 0;
471
472 if (avail != needed) {
473 if (avail > needed) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000474 if (!_canresize(self)) {
475 res = -1;
476 goto finish;
477 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000478 /*
479 0 lo hi old_size
480 | |<----avail----->|<-----tomove------>|
481 | |<-needed->|<-----tomove------>|
482 0 lo new_hi new_size
483 */
484 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
485 Py_SIZE(self) - hi);
486 }
487 /* XXX(nnorwitz): need to verify this can't overflow! */
488 if (PyByteArray_Resize((PyObject *)self,
489 Py_SIZE(self) + needed - avail) < 0) {
490 res = -1;
491 goto finish;
492 }
493 if (avail < needed) {
494 /*
495 0 lo hi old_size
496 | |<-avail->|<-----tomove------>|
497 | |<----needed---->|<-----tomove------>|
498 0 lo new_hi new_size
499 */
500 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
501 Py_SIZE(self) - lo - needed);
502 }
503 }
504
505 if (needed > 0)
506 memcpy(self->ob_bytes + lo, bytes, needed);
507
508
509 finish:
510 if (vbytes.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000511 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000512 return res;
513}
514
515static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000516bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000517{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000518 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000519
520 if (i < 0)
521 i += Py_SIZE(self);
522
523 if (i < 0 || i >= Py_SIZE(self)) {
524 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
525 return -1;
526 }
527
528 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000529 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000530
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000531 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000532 return -1;
533
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000534 self->ob_bytes[i] = ival;
535 return 0;
536}
537
538static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000539bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000540{
541 Py_ssize_t start, stop, step, slicelen, needed;
542 char *bytes;
543
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000544 if (PyIndex_Check(index)) {
545 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000546
547 if (i == -1 && PyErr_Occurred())
548 return -1;
549
550 if (i < 0)
551 i += PyByteArray_GET_SIZE(self);
552
553 if (i < 0 || i >= Py_SIZE(self)) {
554 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
555 return -1;
556 }
557
558 if (values == NULL) {
559 /* Fall through to slice assignment */
560 start = i;
561 stop = i + 1;
562 step = 1;
563 slicelen = 1;
564 }
565 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000566 int ival;
567 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000568 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000569 self->ob_bytes[i] = (char)ival;
570 return 0;
571 }
572 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000573 else if (PySlice_Check(index)) {
574 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000575 PyByteArray_GET_SIZE(self),
576 &start, &stop, &step, &slicelen) < 0) {
577 return -1;
578 }
579 }
580 else {
581 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
582 return -1;
583 }
584
585 if (values == NULL) {
586 bytes = NULL;
587 needed = 0;
588 }
589 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
590 /* Make a copy an call this function recursively */
591 int err;
592 values = PyByteArray_FromObject(values);
593 if (values == NULL)
594 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000595 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000596 Py_DECREF(values);
597 return err;
598 }
599 else {
600 assert(PyByteArray_Check(values));
601 bytes = ((PyByteArrayObject *)values)->ob_bytes;
602 needed = Py_SIZE(values);
603 }
604 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
605 if ((step < 0 && start < stop) ||
606 (step > 0 && start > stop))
607 stop = start;
608 if (step == 1) {
609 if (slicelen != needed) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000610 if (!_canresize(self))
611 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000612 if (slicelen > needed) {
613 /*
614 0 start stop old_size
615 | |<---slicelen--->|<-----tomove------>|
616 | |<-needed->|<-----tomove------>|
617 0 lo new_hi new_size
618 */
619 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
620 Py_SIZE(self) - stop);
621 }
622 if (PyByteArray_Resize((PyObject *)self,
623 Py_SIZE(self) + needed - slicelen) < 0)
624 return -1;
625 if (slicelen < needed) {
626 /*
627 0 lo hi old_size
628 | |<-avail->|<-----tomove------>|
629 | |<----needed---->|<-----tomove------>|
630 0 lo new_hi new_size
631 */
632 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
633 Py_SIZE(self) - start - needed);
634 }
635 }
636
637 if (needed > 0)
638 memcpy(self->ob_bytes + start, bytes, needed);
639
640 return 0;
641 }
642 else {
643 if (needed == 0) {
644 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000645 size_t cur;
646 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000647
Antoine Pitrou5504e892008-12-06 21:27:53 +0000648 if (!_canresize(self))
649 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000650 if (step < 0) {
651 stop = start + 1;
652 start = stop + step * (slicelen - 1) - 1;
653 step = -step;
654 }
655 for (cur = start, i = 0;
656 i < slicelen; cur += step, i++) {
657 Py_ssize_t lim = step - 1;
658
Mark Dickinson66f575b2010-02-14 12:53:32 +0000659 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000660 lim = PyByteArray_GET_SIZE(self) - cur - 1;
661
662 memmove(self->ob_bytes + cur - i,
663 self->ob_bytes + cur + 1, lim);
664 }
665 /* Move the tail of the bytes, in one chunk */
666 cur = start + slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000667 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000668 memmove(self->ob_bytes + cur - slicelen,
669 self->ob_bytes + cur,
670 PyByteArray_GET_SIZE(self) - cur);
671 }
672 if (PyByteArray_Resize((PyObject *)self,
673 PyByteArray_GET_SIZE(self) - slicelen) < 0)
674 return -1;
675
676 return 0;
677 }
678 else {
679 /* Assign slice */
680 Py_ssize_t cur, i;
681
682 if (needed != slicelen) {
683 PyErr_Format(PyExc_ValueError,
684 "attempt to assign bytes of size %zd "
685 "to extended slice of size %zd",
686 needed, slicelen);
687 return -1;
688 }
689 for (cur = start, i = 0; i < slicelen; cur += step, i++)
690 self->ob_bytes[cur] = bytes[i];
691 return 0;
692 }
693 }
694}
695
696static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000697bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000698{
699 static char *kwlist[] = {"source", "encoding", "errors", 0};
700 PyObject *arg = NULL;
701 const char *encoding = NULL;
702 const char *errors = NULL;
703 Py_ssize_t count;
704 PyObject *it;
705 PyObject *(*iternext)(PyObject *);
706
707 if (Py_SIZE(self) != 0) {
708 /* Empty previous contents (yes, do this first of all!) */
709 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
710 return -1;
711 }
712
713 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000714 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000715 &arg, &encoding, &errors))
716 return -1;
717
718 /* Make a quick exit if no first argument */
719 if (arg == NULL) {
720 if (encoding != NULL || errors != NULL) {
721 PyErr_SetString(PyExc_TypeError,
722 "encoding or errors without sequence argument");
723 return -1;
724 }
725 return 0;
726 }
727
728 if (PyUnicode_Check(arg)) {
729 /* Encode via the codec registry */
730 PyObject *encoded, *new;
731 if (encoding == NULL) {
732 PyErr_SetString(PyExc_TypeError,
733 "string argument without an encoding");
734 return -1;
735 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000736 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000737 if (encoded == NULL)
738 return -1;
739 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000740 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000741 Py_DECREF(encoded);
742 if (new == NULL)
743 return -1;
744 Py_DECREF(new);
745 return 0;
746 }
747
748 /* If it's not unicode, there can't be encoding or errors */
749 if (encoding != NULL || errors != NULL) {
750 PyErr_SetString(PyExc_TypeError,
751 "encoding or errors without a string argument");
752 return -1;
753 }
754
755 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000756 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
757 if (count == -1 && PyErr_Occurred()) {
758 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000759 return -1;
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000760 else
761 PyErr_Clear();
762 }
763 else if (count < 0) {
764 PyErr_SetString(PyExc_ValueError, "negative count");
765 return -1;
766 }
767 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000768 if (count > 0) {
769 if (PyByteArray_Resize((PyObject *)self, count))
770 return -1;
771 memset(self->ob_bytes, 0, count);
772 }
773 return 0;
774 }
775
776 /* Use the buffer API */
777 if (PyObject_CheckBuffer(arg)) {
778 Py_ssize_t size;
779 Py_buffer view;
780 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
781 return -1;
782 size = view.len;
783 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
784 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
785 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000786 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000787 return 0;
788 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000789 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000790 return -1;
791 }
792
793 /* XXX Optimize this if the arguments is a list, tuple */
794
795 /* Get the iterator */
796 it = PyObject_GetIter(arg);
797 if (it == NULL)
798 return -1;
799 iternext = *Py_TYPE(it)->tp_iternext;
800
801 /* Run the iterator to exhaustion */
802 for (;;) {
803 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000804 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000805
806 /* Get the next item */
807 item = iternext(it);
808 if (item == NULL) {
809 if (PyErr_Occurred()) {
810 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
811 goto error;
812 PyErr_Clear();
813 }
814 break;
815 }
816
817 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000818 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000819 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000820 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000821 goto error;
822
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000823 /* Append the byte */
824 if (Py_SIZE(self) < self->ob_alloc)
825 Py_SIZE(self)++;
826 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
827 goto error;
828 self->ob_bytes[Py_SIZE(self)-1] = value;
829 }
830
831 /* Clean up and return success */
832 Py_DECREF(it);
833 return 0;
834
835 error:
836 /* Error handling when it != NULL */
837 Py_DECREF(it);
838 return -1;
839}
840
841/* Mostly copied from string_repr, but without the
842 "smart quote" functionality. */
843static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000844bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000845{
846 static const char *hexdigits = "0123456789abcdef";
847 const char *quote_prefix = "bytearray(b";
848 const char *quote_postfix = ")";
849 Py_ssize_t length = Py_SIZE(self);
850 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000851 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000852 PyObject *v;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000853 if (length > (PY_SSIZE_T_MAX - 14) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000854 PyErr_SetString(PyExc_OverflowError,
855 "bytearray object is too large to make repr");
856 return NULL;
857 }
Mark Dickinson66f575b2010-02-14 12:53:32 +0000858 newsize = 14 + 4 * length;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000859 v = PyUnicode_FromUnicode(NULL, newsize);
860 if (v == NULL) {
861 return NULL;
862 }
863 else {
864 register Py_ssize_t i;
865 register Py_UNICODE c;
866 register Py_UNICODE *p;
867 int quote;
868
869 /* Figure out which quote to use; single is preferred */
870 quote = '\'';
871 {
872 char *test, *start;
873 start = PyByteArray_AS_STRING(self);
874 for (test = start; test < start+length; ++test) {
875 if (*test == '"') {
876 quote = '\''; /* back to single */
877 goto decided;
878 }
879 else if (*test == '\'')
880 quote = '"';
881 }
882 decided:
883 ;
884 }
885
886 p = PyUnicode_AS_UNICODE(v);
887 while (*quote_prefix)
888 *p++ = *quote_prefix++;
889 *p++ = quote;
890
891 for (i = 0; i < length; i++) {
892 /* There's at least enough room for a hex escape
893 and a closing quote. */
894 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5);
895 c = self->ob_bytes[i];
896 if (c == '\'' || c == '\\')
897 *p++ = '\\', *p++ = c;
898 else if (c == '\t')
899 *p++ = '\\', *p++ = 't';
900 else if (c == '\n')
901 *p++ = '\\', *p++ = 'n';
902 else if (c == '\r')
903 *p++ = '\\', *p++ = 'r';
904 else if (c == 0)
905 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
906 else if (c < ' ' || c >= 0x7f) {
907 *p++ = '\\';
908 *p++ = 'x';
909 *p++ = hexdigits[(c & 0xf0) >> 4];
910 *p++ = hexdigits[c & 0xf];
911 }
912 else
913 *p++ = c;
914 }
915 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1);
916 *p++ = quote;
917 while (*quote_postfix) {
918 *p++ = *quote_postfix++;
919 }
920 *p = '\0';
921 if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
922 Py_DECREF(v);
923 return NULL;
924 }
925 return v;
926 }
927}
928
929static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000930bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000931{
932 if (Py_BytesWarningFlag) {
933 if (PyErr_WarnEx(PyExc_BytesWarning,
934 "str() on a bytearray instance", 1))
935 return NULL;
936 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000937 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000938}
939
940static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000941bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000942{
943 Py_ssize_t self_size, other_size;
944 Py_buffer self_bytes, other_bytes;
945 PyObject *res;
946 Py_ssize_t minsize;
947 int cmp;
948
949 /* Bytes can be compared to anything that supports the (binary)
950 buffer API. Except that a comparison with Unicode is always an
951 error, even if the comparison is for equality. */
952 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
953 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000954 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000955 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000956 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000957 return NULL;
958 }
959
960 Py_INCREF(Py_NotImplemented);
961 return Py_NotImplemented;
962 }
963
964 self_size = _getbuffer(self, &self_bytes);
965 if (self_size < 0) {
966 PyErr_Clear();
967 Py_INCREF(Py_NotImplemented);
968 return Py_NotImplemented;
969 }
970
971 other_size = _getbuffer(other, &other_bytes);
972 if (other_size < 0) {
973 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +0000974 PyBuffer_Release(&self_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000975 Py_INCREF(Py_NotImplemented);
976 return Py_NotImplemented;
977 }
978
979 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
980 /* Shortcut: if the lengths differ, the objects differ */
981 cmp = (op == Py_NE);
982 }
983 else {
984 minsize = self_size;
985 if (other_size < minsize)
986 minsize = other_size;
987
988 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
989 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
990
991 if (cmp == 0) {
992 if (self_size < other_size)
993 cmp = -1;
994 else if (self_size > other_size)
995 cmp = 1;
996 }
997
998 switch (op) {
999 case Py_LT: cmp = cmp < 0; break;
1000 case Py_LE: cmp = cmp <= 0; break;
1001 case Py_EQ: cmp = cmp == 0; break;
1002 case Py_NE: cmp = cmp != 0; break;
1003 case Py_GT: cmp = cmp > 0; break;
1004 case Py_GE: cmp = cmp >= 0; break;
1005 }
1006 }
1007
1008 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001009 PyBuffer_Release(&self_bytes);
1010 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001011 Py_INCREF(res);
1012 return res;
1013}
1014
1015static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001016bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001017{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001018 if (self->ob_exports > 0) {
1019 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001020 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001021 PyErr_Print();
1022 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001023 if (self->ob_bytes != 0) {
1024 PyMem_Free(self->ob_bytes);
1025 }
1026 Py_TYPE(self)->tp_free((PyObject *)self);
1027}
1028
1029
1030/* -------------------------------------------------------------------- */
1031/* Methods */
1032
1033#define STRINGLIB_CHAR char
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001034#define STRINGLIB_LEN PyByteArray_GET_SIZE
1035#define STRINGLIB_STR PyByteArray_AS_STRING
1036#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001037#define STRINGLIB_ISSPACE Py_ISSPACE
1038#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001039#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1040#define STRINGLIB_MUTABLE 1
1041
1042#include "stringlib/fastsearch.h"
1043#include "stringlib/count.h"
1044#include "stringlib/find.h"
1045#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001046#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001047#include "stringlib/ctype.h"
1048#include "stringlib/transmogrify.h"
1049
1050
1051/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1052were copied from the old char* style string object. */
1053
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001054/* helper macro to fixup start/end slice values */
1055#define ADJUST_INDICES(start, end, len) \
1056 if (end > len) \
1057 end = len; \
1058 else if (end < 0) { \
1059 end += len; \
1060 if (end < 0) \
1061 end = 0; \
1062 } \
1063 if (start < 0) { \
1064 start += len; \
1065 if (start < 0) \
1066 start = 0; \
1067 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001068
1069Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001070bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001071{
1072 PyObject *subobj;
1073 Py_buffer subbuf;
1074 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1075 Py_ssize_t res;
1076
1077 if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
1078 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1079 return -2;
1080 if (_getbuffer(subobj, &subbuf) < 0)
1081 return -2;
1082 if (dir > 0)
1083 res = stringlib_find_slice(
1084 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1085 subbuf.buf, subbuf.len, start, end);
1086 else
1087 res = stringlib_rfind_slice(
1088 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1089 subbuf.buf, subbuf.len, start, end);
Martin v. Löwis423be952008-08-13 15:53:07 +00001090 PyBuffer_Release(&subbuf);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001091 return res;
1092}
1093
1094PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001095"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001096\n\
1097Return the lowest index in B where subsection sub is found,\n\
1098such that sub is contained within s[start,end]. Optional\n\
1099arguments start and end are interpreted as in slice notation.\n\
1100\n\
1101Return -1 on failure.");
1102
1103static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001104bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001105{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001106 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001107 if (result == -2)
1108 return NULL;
1109 return PyLong_FromSsize_t(result);
1110}
1111
1112PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001113"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001114\n\
1115Return the number of non-overlapping occurrences of subsection sub in\n\
1116bytes B[start:end]. Optional arguments start and end are interpreted\n\
1117as in slice notation.");
1118
1119static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001120bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001121{
1122 PyObject *sub_obj;
1123 const char *str = PyByteArray_AS_STRING(self);
1124 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1125 Py_buffer vsub;
1126 PyObject *count_obj;
1127
1128 if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1129 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1130 return NULL;
1131
1132 if (_getbuffer(sub_obj, &vsub) < 0)
1133 return NULL;
1134
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001135 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001136
1137 count_obj = PyLong_FromSsize_t(
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001138 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001139 );
Martin v. Löwis423be952008-08-13 15:53:07 +00001140 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001141 return count_obj;
1142}
1143
1144
1145PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001146"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001147\n\
1148Like B.find() but raise ValueError when the subsection is not found.");
1149
1150static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001151bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001152{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001153 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001154 if (result == -2)
1155 return NULL;
1156 if (result == -1) {
1157 PyErr_SetString(PyExc_ValueError,
1158 "subsection not found");
1159 return NULL;
1160 }
1161 return PyLong_FromSsize_t(result);
1162}
1163
1164
1165PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001166"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001167\n\
1168Return the highest index in B where subsection sub is found,\n\
1169such that sub is contained within s[start,end]. Optional\n\
1170arguments start and end are interpreted as in slice notation.\n\
1171\n\
1172Return -1 on failure.");
1173
1174static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001175bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001176{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001177 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001178 if (result == -2)
1179 return NULL;
1180 return PyLong_FromSsize_t(result);
1181}
1182
1183
1184PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001185"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001186\n\
1187Like B.rfind() but raise ValueError when the subsection is not found.");
1188
1189static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001190bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001191{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001192 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001193 if (result == -2)
1194 return NULL;
1195 if (result == -1) {
1196 PyErr_SetString(PyExc_ValueError,
1197 "subsection not found");
1198 return NULL;
1199 }
1200 return PyLong_FromSsize_t(result);
1201}
1202
1203
1204static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001205bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001206{
1207 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1208 if (ival == -1 && PyErr_Occurred()) {
1209 Py_buffer varg;
1210 int pos;
1211 PyErr_Clear();
1212 if (_getbuffer(arg, &varg) < 0)
1213 return -1;
1214 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1215 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001216 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001217 return pos >= 0;
1218 }
1219 if (ival < 0 || ival >= 256) {
1220 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1221 return -1;
1222 }
1223
1224 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1225}
1226
1227
1228/* Matches the end (direction >= 0) or start (direction < 0) of self
1229 * against substr, using the start and end arguments. Returns
1230 * -1 on error, 0 if not found and 1 if found.
1231 */
1232Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001233_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001234 Py_ssize_t end, int direction)
1235{
1236 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1237 const char* str;
1238 Py_buffer vsubstr;
1239 int rv = 0;
1240
1241 str = PyByteArray_AS_STRING(self);
1242
1243 if (_getbuffer(substr, &vsubstr) < 0)
1244 return -1;
1245
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001246 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001247
1248 if (direction < 0) {
1249 /* startswith */
1250 if (start+vsubstr.len > len) {
1251 goto done;
1252 }
1253 } else {
1254 /* endswith */
1255 if (end-start < vsubstr.len || start > len) {
1256 goto done;
1257 }
1258
1259 if (end-vsubstr.len > start)
1260 start = end - vsubstr.len;
1261 }
1262 if (end-start >= vsubstr.len)
1263 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1264
1265done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001266 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001267 return rv;
1268}
1269
1270
1271PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001272"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001273\n\
1274Return True if B starts with the specified prefix, False otherwise.\n\
1275With optional start, test B beginning at that position.\n\
1276With optional end, stop comparing B at that position.\n\
1277prefix can also be a tuple of strings to try.");
1278
1279static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001280bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001281{
1282 Py_ssize_t start = 0;
1283 Py_ssize_t end = PY_SSIZE_T_MAX;
1284 PyObject *subobj;
1285 int result;
1286
1287 if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
1288 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1289 return NULL;
1290 if (PyTuple_Check(subobj)) {
1291 Py_ssize_t i;
1292 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001293 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001294 PyTuple_GET_ITEM(subobj, i),
1295 start, end, -1);
1296 if (result == -1)
1297 return NULL;
1298 else if (result) {
1299 Py_RETURN_TRUE;
1300 }
1301 }
1302 Py_RETURN_FALSE;
1303 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001304 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001305 if (result == -1)
1306 return NULL;
1307 else
1308 return PyBool_FromLong(result);
1309}
1310
1311PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001312"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001313\n\
1314Return True if B ends with the specified suffix, False otherwise.\n\
1315With optional start, test B beginning at that position.\n\
1316With optional end, stop comparing B at that position.\n\
1317suffix can also be a tuple of strings to try.");
1318
1319static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001320bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001321{
1322 Py_ssize_t start = 0;
1323 Py_ssize_t end = PY_SSIZE_T_MAX;
1324 PyObject *subobj;
1325 int result;
1326
1327 if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
1328 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1329 return NULL;
1330 if (PyTuple_Check(subobj)) {
1331 Py_ssize_t i;
1332 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001333 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001334 PyTuple_GET_ITEM(subobj, i),
1335 start, end, +1);
1336 if (result == -1)
1337 return NULL;
1338 else if (result) {
1339 Py_RETURN_TRUE;
1340 }
1341 }
1342 Py_RETURN_FALSE;
1343 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001344 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001345 if (result == -1)
1346 return NULL;
1347 else
1348 return PyBool_FromLong(result);
1349}
1350
1351
1352PyDoc_STRVAR(translate__doc__,
1353"B.translate(table[, deletechars]) -> bytearray\n\
1354\n\
1355Return a copy of B, where all characters occurring in the\n\
1356optional argument deletechars are removed, and the remaining\n\
1357characters have been mapped through the given translation\n\
1358table, which must be a bytes object of length 256.");
1359
1360static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001361bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001362{
1363 register char *input, *output;
1364 register const char *table;
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001365 register Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001366 PyObject *input_obj = (PyObject*)self;
1367 const char *output_start;
1368 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001369 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001370 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001371 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001372 Py_buffer vtable, vdel;
1373
1374 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1375 &tableobj, &delobj))
1376 return NULL;
1377
Georg Brandlccc47b62008-12-28 11:44:14 +00001378 if (tableobj == Py_None) {
1379 table = NULL;
1380 tableobj = NULL;
1381 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001382 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001383 } else {
1384 if (vtable.len != 256) {
1385 PyErr_SetString(PyExc_ValueError,
1386 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001387 PyBuffer_Release(&vtable);
1388 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001389 }
1390 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001391 }
1392
1393 if (delobj != NULL) {
1394 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001395 if (tableobj != NULL)
1396 PyBuffer_Release(&vtable);
1397 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001398 }
1399 }
1400 else {
1401 vdel.buf = NULL;
1402 vdel.len = 0;
1403 }
1404
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001405 inlen = PyByteArray_GET_SIZE(input_obj);
1406 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1407 if (result == NULL)
1408 goto done;
1409 output_start = output = PyByteArray_AsString(result);
1410 input = PyByteArray_AS_STRING(input_obj);
1411
Georg Brandlccc47b62008-12-28 11:44:14 +00001412 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001413 /* If no deletions are required, use faster code */
1414 for (i = inlen; --i >= 0; ) {
1415 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001416 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001417 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001418 goto done;
1419 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001420
1421 if (table == NULL) {
1422 for (i = 0; i < 256; i++)
1423 trans_table[i] = Py_CHARMASK(i);
1424 } else {
1425 for (i = 0; i < 256; i++)
1426 trans_table[i] = Py_CHARMASK(table[i]);
1427 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001428
1429 for (i = 0; i < vdel.len; i++)
1430 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1431
1432 for (i = inlen; --i >= 0; ) {
1433 c = Py_CHARMASK(*input++);
1434 if (trans_table[c] != -1)
1435 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1436 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001437 }
1438 /* Fix the size of the resulting string */
1439 if (inlen > 0)
1440 PyByteArray_Resize(result, output - output_start);
1441
1442done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001443 if (tableobj != NULL)
1444 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001445 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001446 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001447 return result;
1448}
1449
1450
Georg Brandlabc38772009-04-12 15:51:51 +00001451static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001452bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001453{
1454 return _Py_bytes_maketrans(args);
1455}
1456
1457
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001458/* find and count characters and substrings */
1459
1460#define findchar(target, target_len, c) \
1461 ((char *)memchr((const void *)(target), c, target_len))
1462
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001463
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001464/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001465Py_LOCAL(PyByteArrayObject *)
1466return_self(PyByteArrayObject *self)
1467{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001468 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001469 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1470 PyByteArray_AS_STRING(self),
1471 PyByteArray_GET_SIZE(self));
1472}
1473
1474Py_LOCAL_INLINE(Py_ssize_t)
1475countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1476{
1477 Py_ssize_t count=0;
1478 const char *start=target;
1479 const char *end=target+target_len;
1480
1481 while ( (start=findchar(start, end-start, c)) != NULL ) {
1482 count++;
1483 if (count >= maxcount)
1484 break;
1485 start += 1;
1486 }
1487 return count;
1488}
1489
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001490
1491/* Algorithms for different cases of string replacement */
1492
1493/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1494Py_LOCAL(PyByteArrayObject *)
1495replace_interleave(PyByteArrayObject *self,
1496 const char *to_s, Py_ssize_t to_len,
1497 Py_ssize_t maxcount)
1498{
1499 char *self_s, *result_s;
1500 Py_ssize_t self_len, result_len;
1501 Py_ssize_t count, i, product;
1502 PyByteArrayObject *result;
1503
1504 self_len = PyByteArray_GET_SIZE(self);
1505
1506 /* 1 at the end plus 1 after every character */
1507 count = self_len+1;
1508 if (maxcount < count)
1509 count = maxcount;
1510
1511 /* Check for overflow */
1512 /* result_len = count * to_len + self_len; */
1513 product = count * to_len;
1514 if (product / to_len != count) {
1515 PyErr_SetString(PyExc_OverflowError,
1516 "replace string is too long");
1517 return NULL;
1518 }
1519 result_len = product + self_len;
1520 if (result_len < 0) {
1521 PyErr_SetString(PyExc_OverflowError,
1522 "replace string is too long");
1523 return NULL;
1524 }
1525
1526 if (! (result = (PyByteArrayObject *)
1527 PyByteArray_FromStringAndSize(NULL, result_len)) )
1528 return NULL;
1529
1530 self_s = PyByteArray_AS_STRING(self);
1531 result_s = PyByteArray_AS_STRING(result);
1532
1533 /* TODO: special case single character, which doesn't need memcpy */
1534
1535 /* Lay the first one down (guaranteed this will occur) */
1536 Py_MEMCPY(result_s, to_s, to_len);
1537 result_s += to_len;
1538 count -= 1;
1539
1540 for (i=0; i<count; i++) {
1541 *result_s++ = *self_s++;
1542 Py_MEMCPY(result_s, to_s, to_len);
1543 result_s += to_len;
1544 }
1545
1546 /* Copy the rest of the original string */
1547 Py_MEMCPY(result_s, self_s, self_len-i);
1548
1549 return result;
1550}
1551
1552/* Special case for deleting a single character */
1553/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1554Py_LOCAL(PyByteArrayObject *)
1555replace_delete_single_character(PyByteArrayObject *self,
1556 char from_c, Py_ssize_t maxcount)
1557{
1558 char *self_s, *result_s;
1559 char *start, *next, *end;
1560 Py_ssize_t self_len, result_len;
1561 Py_ssize_t count;
1562 PyByteArrayObject *result;
1563
1564 self_len = PyByteArray_GET_SIZE(self);
1565 self_s = PyByteArray_AS_STRING(self);
1566
1567 count = countchar(self_s, self_len, from_c, maxcount);
1568 if (count == 0) {
1569 return return_self(self);
1570 }
1571
1572 result_len = self_len - count; /* from_len == 1 */
1573 assert(result_len>=0);
1574
1575 if ( (result = (PyByteArrayObject *)
1576 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1577 return NULL;
1578 result_s = PyByteArray_AS_STRING(result);
1579
1580 start = self_s;
1581 end = self_s + self_len;
1582 while (count-- > 0) {
1583 next = findchar(start, end-start, from_c);
1584 if (next == NULL)
1585 break;
1586 Py_MEMCPY(result_s, start, next-start);
1587 result_s += (next-start);
1588 start = next+1;
1589 }
1590 Py_MEMCPY(result_s, start, end-start);
1591
1592 return result;
1593}
1594
1595/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1596
1597Py_LOCAL(PyByteArrayObject *)
1598replace_delete_substring(PyByteArrayObject *self,
1599 const char *from_s, Py_ssize_t from_len,
1600 Py_ssize_t maxcount)
1601{
1602 char *self_s, *result_s;
1603 char *start, *next, *end;
1604 Py_ssize_t self_len, result_len;
1605 Py_ssize_t count, offset;
1606 PyByteArrayObject *result;
1607
1608 self_len = PyByteArray_GET_SIZE(self);
1609 self_s = PyByteArray_AS_STRING(self);
1610
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001611 count = stringlib_count(self_s, self_len,
1612 from_s, from_len,
1613 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001614
1615 if (count == 0) {
1616 /* no matches */
1617 return return_self(self);
1618 }
1619
1620 result_len = self_len - (count * from_len);
1621 assert (result_len>=0);
1622
1623 if ( (result = (PyByteArrayObject *)
1624 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1625 return NULL;
1626
1627 result_s = PyByteArray_AS_STRING(result);
1628
1629 start = self_s;
1630 end = self_s + self_len;
1631 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001632 offset = stringlib_find(start, end-start,
1633 from_s, from_len,
1634 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001635 if (offset == -1)
1636 break;
1637 next = start + offset;
1638
1639 Py_MEMCPY(result_s, start, next-start);
1640
1641 result_s += (next-start);
1642 start = next+from_len;
1643 }
1644 Py_MEMCPY(result_s, start, end-start);
1645 return result;
1646}
1647
1648/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1649Py_LOCAL(PyByteArrayObject *)
1650replace_single_character_in_place(PyByteArrayObject *self,
1651 char from_c, char to_c,
1652 Py_ssize_t maxcount)
1653{
1654 char *self_s, *result_s, *start, *end, *next;
1655 Py_ssize_t self_len;
1656 PyByteArrayObject *result;
1657
1658 /* The result string will be the same size */
1659 self_s = PyByteArray_AS_STRING(self);
1660 self_len = PyByteArray_GET_SIZE(self);
1661
1662 next = findchar(self_s, self_len, from_c);
1663
1664 if (next == NULL) {
1665 /* No matches; return the original bytes */
1666 return return_self(self);
1667 }
1668
1669 /* Need to make a new bytes */
1670 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1671 if (result == NULL)
1672 return NULL;
1673 result_s = PyByteArray_AS_STRING(result);
1674 Py_MEMCPY(result_s, self_s, self_len);
1675
1676 /* change everything in-place, starting with this one */
1677 start = result_s + (next-self_s);
1678 *start = to_c;
1679 start++;
1680 end = result_s + self_len;
1681
1682 while (--maxcount > 0) {
1683 next = findchar(start, end-start, from_c);
1684 if (next == NULL)
1685 break;
1686 *next = to_c;
1687 start = next+1;
1688 }
1689
1690 return result;
1691}
1692
1693/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1694Py_LOCAL(PyByteArrayObject *)
1695replace_substring_in_place(PyByteArrayObject *self,
1696 const char *from_s, Py_ssize_t from_len,
1697 const char *to_s, Py_ssize_t to_len,
1698 Py_ssize_t maxcount)
1699{
1700 char *result_s, *start, *end;
1701 char *self_s;
1702 Py_ssize_t self_len, offset;
1703 PyByteArrayObject *result;
1704
1705 /* The result bytes will be the same size */
1706
1707 self_s = PyByteArray_AS_STRING(self);
1708 self_len = PyByteArray_GET_SIZE(self);
1709
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001710 offset = stringlib_find(self_s, self_len,
1711 from_s, from_len,
1712 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001713 if (offset == -1) {
1714 /* No matches; return the original bytes */
1715 return return_self(self);
1716 }
1717
1718 /* Need to make a new bytes */
1719 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1720 if (result == NULL)
1721 return NULL;
1722 result_s = PyByteArray_AS_STRING(result);
1723 Py_MEMCPY(result_s, self_s, self_len);
1724
1725 /* change everything in-place, starting with this one */
1726 start = result_s + offset;
1727 Py_MEMCPY(start, to_s, from_len);
1728 start += from_len;
1729 end = result_s + self_len;
1730
1731 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001732 offset = stringlib_find(start, end-start,
1733 from_s, from_len,
1734 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001735 if (offset==-1)
1736 break;
1737 Py_MEMCPY(start+offset, to_s, from_len);
1738 start += offset+from_len;
1739 }
1740
1741 return result;
1742}
1743
1744/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1745Py_LOCAL(PyByteArrayObject *)
1746replace_single_character(PyByteArrayObject *self,
1747 char from_c,
1748 const char *to_s, Py_ssize_t to_len,
1749 Py_ssize_t maxcount)
1750{
1751 char *self_s, *result_s;
1752 char *start, *next, *end;
1753 Py_ssize_t self_len, result_len;
1754 Py_ssize_t count, product;
1755 PyByteArrayObject *result;
1756
1757 self_s = PyByteArray_AS_STRING(self);
1758 self_len = PyByteArray_GET_SIZE(self);
1759
1760 count = countchar(self_s, self_len, from_c, maxcount);
1761 if (count == 0) {
1762 /* no matches, return unchanged */
1763 return return_self(self);
1764 }
1765
1766 /* use the difference between current and new, hence the "-1" */
1767 /* result_len = self_len + count * (to_len-1) */
1768 product = count * (to_len-1);
1769 if (product / (to_len-1) != count) {
1770 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1771 return NULL;
1772 }
1773 result_len = self_len + product;
1774 if (result_len < 0) {
1775 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1776 return NULL;
1777 }
1778
1779 if ( (result = (PyByteArrayObject *)
1780 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1781 return NULL;
1782 result_s = PyByteArray_AS_STRING(result);
1783
1784 start = self_s;
1785 end = self_s + self_len;
1786 while (count-- > 0) {
1787 next = findchar(start, end-start, from_c);
1788 if (next == NULL)
1789 break;
1790
1791 if (next == start) {
1792 /* replace with the 'to' */
1793 Py_MEMCPY(result_s, to_s, to_len);
1794 result_s += to_len;
1795 start += 1;
1796 } else {
1797 /* copy the unchanged old then the 'to' */
1798 Py_MEMCPY(result_s, start, next-start);
1799 result_s += (next-start);
1800 Py_MEMCPY(result_s, to_s, to_len);
1801 result_s += to_len;
1802 start = next+1;
1803 }
1804 }
1805 /* Copy the remainder of the remaining bytes */
1806 Py_MEMCPY(result_s, start, end-start);
1807
1808 return result;
1809}
1810
1811/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1812Py_LOCAL(PyByteArrayObject *)
1813replace_substring(PyByteArrayObject *self,
1814 const char *from_s, Py_ssize_t from_len,
1815 const char *to_s, Py_ssize_t to_len,
1816 Py_ssize_t maxcount)
1817{
1818 char *self_s, *result_s;
1819 char *start, *next, *end;
1820 Py_ssize_t self_len, result_len;
1821 Py_ssize_t count, offset, product;
1822 PyByteArrayObject *result;
1823
1824 self_s = PyByteArray_AS_STRING(self);
1825 self_len = PyByteArray_GET_SIZE(self);
1826
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001827 count = stringlib_count(self_s, self_len,
1828 from_s, from_len,
1829 maxcount);
1830
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001831 if (count == 0) {
1832 /* no matches, return unchanged */
1833 return return_self(self);
1834 }
1835
1836 /* Check for overflow */
1837 /* result_len = self_len + count * (to_len-from_len) */
1838 product = count * (to_len-from_len);
1839 if (product / (to_len-from_len) != count) {
1840 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1841 return NULL;
1842 }
1843 result_len = self_len + product;
1844 if (result_len < 0) {
1845 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1846 return NULL;
1847 }
1848
1849 if ( (result = (PyByteArrayObject *)
1850 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1851 return NULL;
1852 result_s = PyByteArray_AS_STRING(result);
1853
1854 start = self_s;
1855 end = self_s + self_len;
1856 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001857 offset = stringlib_find(start, end-start,
1858 from_s, from_len,
1859 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001860 if (offset == -1)
1861 break;
1862 next = start+offset;
1863 if (next == start) {
1864 /* replace with the 'to' */
1865 Py_MEMCPY(result_s, to_s, to_len);
1866 result_s += to_len;
1867 start += from_len;
1868 } else {
1869 /* copy the unchanged old then the 'to' */
1870 Py_MEMCPY(result_s, start, next-start);
1871 result_s += (next-start);
1872 Py_MEMCPY(result_s, to_s, to_len);
1873 result_s += to_len;
1874 start = next+from_len;
1875 }
1876 }
1877 /* Copy the remainder of the remaining bytes */
1878 Py_MEMCPY(result_s, start, end-start);
1879
1880 return result;
1881}
1882
1883
1884Py_LOCAL(PyByteArrayObject *)
1885replace(PyByteArrayObject *self,
1886 const char *from_s, Py_ssize_t from_len,
1887 const char *to_s, Py_ssize_t to_len,
1888 Py_ssize_t maxcount)
1889{
1890 if (maxcount < 0) {
1891 maxcount = PY_SSIZE_T_MAX;
1892 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1893 /* nothing to do; return the original bytes */
1894 return return_self(self);
1895 }
1896
1897 if (maxcount == 0 ||
1898 (from_len == 0 && to_len == 0)) {
1899 /* nothing to do; return the original bytes */
1900 return return_self(self);
1901 }
1902
1903 /* Handle zero-length special cases */
1904
1905 if (from_len == 0) {
1906 /* insert the 'to' bytes everywhere. */
1907 /* >>> "Python".replace("", ".") */
1908 /* '.P.y.t.h.o.n.' */
1909 return replace_interleave(self, to_s, to_len, maxcount);
1910 }
1911
1912 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1913 /* point for an empty self bytes to generate a non-empty bytes */
1914 /* Special case so the remaining code always gets a non-empty bytes */
1915 if (PyByteArray_GET_SIZE(self) == 0) {
1916 return return_self(self);
1917 }
1918
1919 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00001920 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001921 if (from_len == 1) {
1922 return replace_delete_single_character(
1923 self, from_s[0], maxcount);
1924 } else {
1925 return replace_delete_substring(self, from_s, from_len, maxcount);
1926 }
1927 }
1928
1929 /* Handle special case where both bytes have the same length */
1930
1931 if (from_len == to_len) {
1932 if (from_len == 1) {
1933 return replace_single_character_in_place(
1934 self,
1935 from_s[0],
1936 to_s[0],
1937 maxcount);
1938 } else {
1939 return replace_substring_in_place(
1940 self, from_s, from_len, to_s, to_len, maxcount);
1941 }
1942 }
1943
1944 /* Otherwise use the more generic algorithms */
1945 if (from_len == 1) {
1946 return replace_single_character(self, from_s[0],
1947 to_s, to_len, maxcount);
1948 } else {
1949 /* len('from')>=2, len('to')>=1 */
1950 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
1951 }
1952}
1953
1954
1955PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001956"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001957\n\
1958Return a copy of B with all occurrences of subsection\n\
1959old replaced by new. If the optional argument count is\n\
1960given, only the first count occurrences are replaced.");
1961
1962static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001963bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001964{
1965 Py_ssize_t count = -1;
1966 PyObject *from, *to, *res;
1967 Py_buffer vfrom, vto;
1968
1969 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
1970 return NULL;
1971
1972 if (_getbuffer(from, &vfrom) < 0)
1973 return NULL;
1974 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +00001975 PyBuffer_Release(&vfrom);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001976 return NULL;
1977 }
1978
1979 res = (PyObject *)replace((PyByteArrayObject *) self,
1980 vfrom.buf, vfrom.len,
1981 vto.buf, vto.len, count);
1982
Martin v. Löwis423be952008-08-13 15:53:07 +00001983 PyBuffer_Release(&vfrom);
1984 PyBuffer_Release(&vto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001985 return res;
1986}
1987
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001988PyDoc_STRVAR(split__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001989"B.split([sep[, maxsplit]]) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001990\n\
1991Return a list of the sections in B, using sep as the delimiter.\n\
1992If sep is not given, B is split on ASCII whitespace characters\n\
1993(space, tab, return, newline, formfeed, vertical tab).\n\
1994If maxsplit is given, at most maxsplit splits are done.");
1995
1996static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001997bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001998{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001999 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2000 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002001 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002002 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002003 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002004
2005 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2006 return NULL;
2007 if (maxsplit < 0)
2008 maxsplit = PY_SSIZE_T_MAX;
2009
2010 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002011 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002012
2013 if (_getbuffer(subobj, &vsub) < 0)
2014 return NULL;
2015 sub = vsub.buf;
2016 n = vsub.len;
2017
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002018 list = stringlib_split(
2019 (PyObject*) self, s, len, sub, n, maxsplit
2020 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002021 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002022 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002023}
2024
2025PyDoc_STRVAR(partition__doc__,
2026"B.partition(sep) -> (head, sep, tail)\n\
2027\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002028Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002029the separator itself, and the part after it. If the separator is not\n\
2030found, returns B and two empty bytearray objects.");
2031
2032static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002033bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002034{
2035 PyObject *bytesep, *result;
2036
2037 bytesep = PyByteArray_FromObject(sep_obj);
2038 if (! bytesep)
2039 return NULL;
2040
2041 result = stringlib_partition(
2042 (PyObject*) self,
2043 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2044 bytesep,
2045 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2046 );
2047
2048 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002049 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002050}
2051
2052PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002053"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002054\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002055Search for the separator sep in B, starting at the end of B,\n\
2056and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002057part after it. If the separator is not found, returns two empty\n\
2058bytearray objects and B.");
2059
2060static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002061bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002062{
2063 PyObject *bytesep, *result;
2064
2065 bytesep = PyByteArray_FromObject(sep_obj);
2066 if (! bytesep)
2067 return NULL;
2068
2069 result = stringlib_rpartition(
2070 (PyObject*) self,
2071 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2072 bytesep,
2073 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2074 );
2075
2076 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002077 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002078}
2079
2080PyDoc_STRVAR(rsplit__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002081"B.rsplit(sep[, maxsplit]) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002082\n\
2083Return a list of the sections in B, using sep as the delimiter,\n\
2084starting at the end of B and working to the front.\n\
2085If sep is not given, B is split on ASCII whitespace characters\n\
2086(space, tab, return, newline, formfeed, vertical tab).\n\
2087If maxsplit is given, at most maxsplit splits are done.");
2088
2089static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002090bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002091{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002092 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2093 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002094 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002095 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002096 Py_buffer vsub;
2097
2098 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2099 return NULL;
2100 if (maxsplit < 0)
2101 maxsplit = PY_SSIZE_T_MAX;
2102
2103 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002104 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002105
2106 if (_getbuffer(subobj, &vsub) < 0)
2107 return NULL;
2108 sub = vsub.buf;
2109 n = vsub.len;
2110
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002111 list = stringlib_rsplit(
2112 (PyObject*) self, s, len, sub, n, maxsplit
2113 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002114 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002115 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002116}
2117
2118PyDoc_STRVAR(reverse__doc__,
2119"B.reverse() -> None\n\
2120\n\
2121Reverse the order of the values in B in place.");
2122static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002123bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002124{
2125 char swap, *head, *tail;
2126 Py_ssize_t i, j, n = Py_SIZE(self);
2127
2128 j = n / 2;
2129 head = self->ob_bytes;
2130 tail = head + n - 1;
2131 for (i = 0; i < j; i++) {
2132 swap = *head;
2133 *head++ = *tail;
2134 *tail-- = swap;
2135 }
2136
2137 Py_RETURN_NONE;
2138}
2139
2140PyDoc_STRVAR(insert__doc__,
2141"B.insert(index, int) -> None\n\
2142\n\
2143Insert a single item into the bytearray before the given index.");
2144static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002145bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002146{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002147 PyObject *value;
2148 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002149 Py_ssize_t where, n = Py_SIZE(self);
2150
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002151 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002152 return NULL;
2153
2154 if (n == PY_SSIZE_T_MAX) {
2155 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002156 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002157 return NULL;
2158 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002159 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002160 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002161 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2162 return NULL;
2163
2164 if (where < 0) {
2165 where += n;
2166 if (where < 0)
2167 where = 0;
2168 }
2169 if (where > n)
2170 where = n;
2171 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002172 self->ob_bytes[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002173
2174 Py_RETURN_NONE;
2175}
2176
2177PyDoc_STRVAR(append__doc__,
2178"B.append(int) -> None\n\
2179\n\
2180Append a single item to the end of B.");
2181static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002182bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002183{
2184 int value;
2185 Py_ssize_t n = Py_SIZE(self);
2186
2187 if (! _getbytevalue(arg, &value))
2188 return NULL;
2189 if (n == PY_SSIZE_T_MAX) {
2190 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002191 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002192 return NULL;
2193 }
2194 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2195 return NULL;
2196
2197 self->ob_bytes[n] = value;
2198
2199 Py_RETURN_NONE;
2200}
2201
2202PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002203"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002204\n\
2205Append all the elements from the iterator or sequence to the\n\
2206end of B.");
2207static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002208bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002209{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002210 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002211 Py_ssize_t buf_size = 0, len = 0;
2212 int value;
2213 char *buf;
2214
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002215 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002216 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002217 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002218 return NULL;
2219
2220 Py_RETURN_NONE;
2221 }
2222
2223 it = PyObject_GetIter(arg);
2224 if (it == NULL)
2225 return NULL;
2226
2227 /* Try to determine the length of the argument. 32 is abitrary. */
2228 buf_size = _PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002229 if (buf_size == -1) {
2230 Py_DECREF(it);
2231 return NULL;
2232 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002233
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002234 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2235 if (bytearray_obj == NULL)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002236 return NULL;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002237 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002238
2239 while ((item = PyIter_Next(it)) != NULL) {
2240 if (! _getbytevalue(item, &value)) {
2241 Py_DECREF(item);
2242 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002243 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002244 return NULL;
2245 }
2246 buf[len++] = value;
2247 Py_DECREF(item);
2248
2249 if (len >= buf_size) {
2250 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002251 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002252 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002253 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002254 return NULL;
2255 }
2256 /* Recompute the `buf' pointer, since the resizing operation may
2257 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002258 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002259 }
2260 }
2261 Py_DECREF(it);
2262
2263 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002264 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2265 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002266 return NULL;
2267 }
2268
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002269 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002270 return NULL;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002271 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002272
2273 Py_RETURN_NONE;
2274}
2275
2276PyDoc_STRVAR(pop__doc__,
2277"B.pop([index]) -> int\n\
2278\n\
2279Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002280argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002281static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002282bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002283{
2284 int value;
2285 Py_ssize_t where = -1, n = Py_SIZE(self);
2286
2287 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2288 return NULL;
2289
2290 if (n == 0) {
2291 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002292 "cannot pop an empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002293 return NULL;
2294 }
2295 if (where < 0)
2296 where += Py_SIZE(self);
2297 if (where < 0 || where >= Py_SIZE(self)) {
2298 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2299 return NULL;
2300 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002301 if (!_canresize(self))
2302 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002303
2304 value = self->ob_bytes[where];
2305 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2306 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2307 return NULL;
2308
Mark Dickinson54a3db92009-09-06 10:19:23 +00002309 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002310}
2311
2312PyDoc_STRVAR(remove__doc__,
2313"B.remove(int) -> None\n\
2314\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002315Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002316static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002317bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002318{
2319 int value;
2320 Py_ssize_t where, n = Py_SIZE(self);
2321
2322 if (! _getbytevalue(arg, &value))
2323 return NULL;
2324
2325 for (where = 0; where < n; where++) {
2326 if (self->ob_bytes[where] == value)
2327 break;
2328 }
2329 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002330 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002331 return NULL;
2332 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002333 if (!_canresize(self))
2334 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002335
2336 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2337 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2338 return NULL;
2339
2340 Py_RETURN_NONE;
2341}
2342
2343/* XXX These two helpers could be optimized if argsize == 1 */
2344
2345static Py_ssize_t
2346lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2347 void *argptr, Py_ssize_t argsize)
2348{
2349 Py_ssize_t i = 0;
2350 while (i < mysize && memchr(argptr, myptr[i], argsize))
2351 i++;
2352 return i;
2353}
2354
2355static Py_ssize_t
2356rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2357 void *argptr, Py_ssize_t argsize)
2358{
2359 Py_ssize_t i = mysize - 1;
2360 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2361 i--;
2362 return i + 1;
2363}
2364
2365PyDoc_STRVAR(strip__doc__,
2366"B.strip([bytes]) -> bytearray\n\
2367\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002368Strip leading and trailing bytes contained in the argument\n\
2369and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002370If the argument is omitted, strip ASCII whitespace.");
2371static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002372bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002373{
2374 Py_ssize_t left, right, mysize, argsize;
2375 void *myptr, *argptr;
2376 PyObject *arg = Py_None;
2377 Py_buffer varg;
2378 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2379 return NULL;
2380 if (arg == Py_None) {
2381 argptr = "\t\n\r\f\v ";
2382 argsize = 6;
2383 }
2384 else {
2385 if (_getbuffer(arg, &varg) < 0)
2386 return NULL;
2387 argptr = varg.buf;
2388 argsize = varg.len;
2389 }
2390 myptr = self->ob_bytes;
2391 mysize = Py_SIZE(self);
2392 left = lstrip_helper(myptr, mysize, argptr, argsize);
2393 if (left == mysize)
2394 right = left;
2395 else
2396 right = rstrip_helper(myptr, mysize, argptr, argsize);
2397 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002398 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002399 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2400}
2401
2402PyDoc_STRVAR(lstrip__doc__,
2403"B.lstrip([bytes]) -> bytearray\n\
2404\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002405Strip leading bytes contained in the argument\n\
2406and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002407If the argument is omitted, strip leading ASCII whitespace.");
2408static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002409bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002410{
2411 Py_ssize_t left, right, mysize, argsize;
2412 void *myptr, *argptr;
2413 PyObject *arg = Py_None;
2414 Py_buffer varg;
2415 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2416 return NULL;
2417 if (arg == Py_None) {
2418 argptr = "\t\n\r\f\v ";
2419 argsize = 6;
2420 }
2421 else {
2422 if (_getbuffer(arg, &varg) < 0)
2423 return NULL;
2424 argptr = varg.buf;
2425 argsize = varg.len;
2426 }
2427 myptr = self->ob_bytes;
2428 mysize = Py_SIZE(self);
2429 left = lstrip_helper(myptr, mysize, argptr, argsize);
2430 right = mysize;
2431 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002432 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002433 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2434}
2435
2436PyDoc_STRVAR(rstrip__doc__,
2437"B.rstrip([bytes]) -> bytearray\n\
2438\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002439Strip trailing bytes contained in the argument\n\
2440and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002441If the argument is omitted, strip trailing ASCII whitespace.");
2442static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002443bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002444{
2445 Py_ssize_t left, right, mysize, argsize;
2446 void *myptr, *argptr;
2447 PyObject *arg = Py_None;
2448 Py_buffer varg;
2449 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2450 return NULL;
2451 if (arg == Py_None) {
2452 argptr = "\t\n\r\f\v ";
2453 argsize = 6;
2454 }
2455 else {
2456 if (_getbuffer(arg, &varg) < 0)
2457 return NULL;
2458 argptr = varg.buf;
2459 argsize = varg.len;
2460 }
2461 myptr = self->ob_bytes;
2462 mysize = Py_SIZE(self);
2463 left = 0;
2464 right = rstrip_helper(myptr, mysize, argptr, argsize);
2465 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002466 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002467 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2468}
2469
2470PyDoc_STRVAR(decode_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002471"B.decode([encoding[, errors]]) -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002472\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002473Decode B using the codec registered for encoding. encoding defaults\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002474to the default encoding. errors may be given to set a different error\n\
2475handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2476a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2477as well as any other name registered with codecs.register_error that is\n\
2478able to handle UnicodeDecodeErrors.");
2479
2480static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002481bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002482{
2483 const char *encoding = NULL;
2484 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002485 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002486
Benjamin Peterson308d6372009-09-18 21:42:35 +00002487 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002488 return NULL;
2489 if (encoding == NULL)
2490 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002491 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002492}
2493
2494PyDoc_STRVAR(alloc_doc,
2495"B.__alloc__() -> int\n\
2496\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002497Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002498
2499static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002500bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002501{
2502 return PyLong_FromSsize_t(self->ob_alloc);
2503}
2504
2505PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002506"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002507\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002508Concatenate any number of bytes/bytearray objects, with B\n\
2509in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002510
2511static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002512bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002513{
2514 PyObject *seq;
2515 Py_ssize_t mysize = Py_SIZE(self);
2516 Py_ssize_t i;
2517 Py_ssize_t n;
2518 PyObject **items;
2519 Py_ssize_t totalsize = 0;
2520 PyObject *result;
2521 char *dest;
2522
2523 seq = PySequence_Fast(it, "can only join an iterable");
2524 if (seq == NULL)
2525 return NULL;
2526 n = PySequence_Fast_GET_SIZE(seq);
2527 items = PySequence_Fast_ITEMS(seq);
2528
2529 /* Compute the total size, and check that they are all bytes */
2530 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2531 for (i = 0; i < n; i++) {
2532 PyObject *obj = items[i];
2533 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2534 PyErr_Format(PyExc_TypeError,
2535 "can only join an iterable of bytes "
2536 "(item %ld has type '%.100s')",
2537 /* XXX %ld isn't right on Win64 */
2538 (long)i, Py_TYPE(obj)->tp_name);
2539 goto error;
2540 }
2541 if (i > 0)
2542 totalsize += mysize;
2543 totalsize += Py_SIZE(obj);
2544 if (totalsize < 0) {
2545 PyErr_NoMemory();
2546 goto error;
2547 }
2548 }
2549
2550 /* Allocate the result, and copy the bytes */
2551 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2552 if (result == NULL)
2553 goto error;
2554 dest = PyByteArray_AS_STRING(result);
2555 for (i = 0; i < n; i++) {
2556 PyObject *obj = items[i];
2557 Py_ssize_t size = Py_SIZE(obj);
2558 char *buf;
2559 if (PyByteArray_Check(obj))
2560 buf = PyByteArray_AS_STRING(obj);
2561 else
2562 buf = PyBytes_AS_STRING(obj);
2563 if (i) {
2564 memcpy(dest, self->ob_bytes, mysize);
2565 dest += mysize;
2566 }
2567 memcpy(dest, buf, size);
2568 dest += size;
2569 }
2570
2571 /* Done */
2572 Py_DECREF(seq);
2573 return result;
2574
2575 /* Error handling */
2576 error:
2577 Py_DECREF(seq);
2578 return NULL;
2579}
2580
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002581PyDoc_STRVAR(splitlines__doc__,
2582"B.splitlines([keepends]) -> list of lines\n\
2583\n\
2584Return a list of the lines in B, breaking at line boundaries.\n\
2585Line breaks are not included in the resulting list unless keepends\n\
2586is given and true.");
2587
2588static PyObject*
2589bytearray_splitlines(PyObject *self, PyObject *args)
2590{
2591 int keepends = 0;
2592
2593 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2594 return NULL;
2595
2596 return stringlib_splitlines(
2597 (PyObject*) self, PyByteArray_AS_STRING(self),
2598 PyByteArray_GET_SIZE(self), keepends
2599 );
2600}
2601
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002602PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002603"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002604\n\
2605Create a bytearray object from a string of hexadecimal numbers.\n\
2606Spaces between two numbers are accepted.\n\
2607Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2608
2609static int
2610hex_digit_to_int(Py_UNICODE c)
2611{
2612 if (c >= 128)
2613 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002614 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002615 return c - '0';
2616 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002617 if (Py_ISUPPER(c))
2618 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002619 if (c >= 'a' && c <= 'f')
2620 return c - 'a' + 10;
2621 }
2622 return -1;
2623}
2624
2625static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002626bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002627{
2628 PyObject *newbytes, *hexobj;
2629 char *buf;
2630 Py_UNICODE *hex;
2631 Py_ssize_t hexlen, byteslen, i, j;
2632 int top, bot;
2633
2634 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2635 return NULL;
2636 assert(PyUnicode_Check(hexobj));
2637 hexlen = PyUnicode_GET_SIZE(hexobj);
2638 hex = PyUnicode_AS_UNICODE(hexobj);
2639 byteslen = hexlen/2; /* This overestimates if there are spaces */
2640 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2641 if (!newbytes)
2642 return NULL;
2643 buf = PyByteArray_AS_STRING(newbytes);
2644 for (i = j = 0; i < hexlen; i += 2) {
2645 /* skip over spaces in the input */
2646 while (hex[i] == ' ')
2647 i++;
2648 if (i >= hexlen)
2649 break;
2650 top = hex_digit_to_int(hex[i]);
2651 bot = hex_digit_to_int(hex[i+1]);
2652 if (top == -1 || bot == -1) {
2653 PyErr_Format(PyExc_ValueError,
2654 "non-hexadecimal number found in "
2655 "fromhex() arg at position %zd", i);
2656 goto error;
2657 }
2658 buf[j++] = (top << 4) + bot;
2659 }
2660 if (PyByteArray_Resize(newbytes, j) < 0)
2661 goto error;
2662 return newbytes;
2663
2664 error:
2665 Py_DECREF(newbytes);
2666 return NULL;
2667}
2668
2669PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2670
2671static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002672bytearray_reduce(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002673{
2674 PyObject *latin1, *dict;
2675 if (self->ob_bytes)
2676 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2677 Py_SIZE(self), NULL);
2678 else
2679 latin1 = PyUnicode_FromString("");
2680
2681 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2682 if (dict == NULL) {
2683 PyErr_Clear();
2684 dict = Py_None;
2685 Py_INCREF(dict);
2686 }
2687
2688 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2689}
2690
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002691PyDoc_STRVAR(sizeof_doc,
2692"B.__sizeof__() -> int\n\
2693 \n\
2694Returns the size of B in memory, in bytes");
2695static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002696bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002697{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002698 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002699
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002700 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2701 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002702}
2703
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002704static PySequenceMethods bytearray_as_sequence = {
2705 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002706 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002707 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2708 (ssizeargfunc)bytearray_getitem, /* sq_item */
2709 0, /* sq_slice */
2710 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2711 0, /* sq_ass_slice */
2712 (objobjproc)bytearray_contains, /* sq_contains */
2713 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2714 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002715};
2716
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002717static PyMappingMethods bytearray_as_mapping = {
2718 (lenfunc)bytearray_length,
2719 (binaryfunc)bytearray_subscript,
2720 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002721};
2722
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002723static PyBufferProcs bytearray_as_buffer = {
2724 (getbufferproc)bytearray_getbuffer,
2725 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002726};
2727
2728static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002729bytearray_methods[] = {
2730 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2731 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2732 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2733 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002734 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2735 _Py_capitalize__doc__},
2736 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002737 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002738 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002739 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002740 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2741 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002742 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2743 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2744 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002745 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002746 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2747 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002748 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2749 _Py_isalnum__doc__},
2750 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2751 _Py_isalpha__doc__},
2752 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2753 _Py_isdigit__doc__},
2754 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2755 _Py_islower__doc__},
2756 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2757 _Py_isspace__doc__},
2758 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2759 _Py_istitle__doc__},
2760 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2761 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002762 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002763 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2764 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002765 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2766 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002767 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002768 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2769 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2770 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2771 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2772 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2773 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2774 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002775 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002776 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2777 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2778 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2779 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002780 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002781 splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002782 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002783 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002784 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002785 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2786 _Py_swapcase__doc__},
2787 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002788 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002789 translate__doc__},
2790 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2791 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2792 {NULL}
2793};
2794
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002795PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002796"bytearray(iterable_of_ints) -> bytearray\n\
2797bytearray(string, encoding[, errors]) -> bytearray\n\
2798bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray\n\
2799bytearray(memory_view) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002800\n\
2801Construct an mutable bytearray object from:\n\
2802 - an iterable yielding integers in range(256)\n\
2803 - a text string encoded using the specified encoding\n\
2804 - a bytes or a bytearray object\n\
2805 - any object implementing the buffer API.\n\
2806\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002807bytearray(int) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002808\n\
2809Construct a zero-initialized bytearray of the given length.");
2810
2811
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002812static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002813
2814PyTypeObject PyByteArray_Type = {
2815 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2816 "bytearray",
2817 sizeof(PyByteArrayObject),
2818 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002819 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002820 0, /* tp_print */
2821 0, /* tp_getattr */
2822 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002823 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002824 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002825 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002826 &bytearray_as_sequence, /* tp_as_sequence */
2827 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002828 0, /* tp_hash */
2829 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002830 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002831 PyObject_GenericGetAttr, /* tp_getattro */
2832 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002833 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002834 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002835 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002836 0, /* tp_traverse */
2837 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002838 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002839 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002840 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002841 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002842 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002843 0, /* tp_members */
2844 0, /* tp_getset */
2845 0, /* tp_base */
2846 0, /* tp_dict */
2847 0, /* tp_descr_get */
2848 0, /* tp_descr_set */
2849 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002850 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002851 PyType_GenericAlloc, /* tp_alloc */
2852 PyType_GenericNew, /* tp_new */
2853 PyObject_Del, /* tp_free */
2854};
2855
2856/*********************** Bytes Iterator ****************************/
2857
2858typedef struct {
2859 PyObject_HEAD
2860 Py_ssize_t it_index;
2861 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2862} bytesiterobject;
2863
2864static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002865bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002866{
2867 _PyObject_GC_UNTRACK(it);
2868 Py_XDECREF(it->it_seq);
2869 PyObject_GC_Del(it);
2870}
2871
2872static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002873bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002874{
2875 Py_VISIT(it->it_seq);
2876 return 0;
2877}
2878
2879static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002880bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002881{
2882 PyByteArrayObject *seq;
2883 PyObject *item;
2884
2885 assert(it != NULL);
2886 seq = it->it_seq;
2887 if (seq == NULL)
2888 return NULL;
2889 assert(PyByteArray_Check(seq));
2890
2891 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2892 item = PyLong_FromLong(
2893 (unsigned char)seq->ob_bytes[it->it_index]);
2894 if (item != NULL)
2895 ++it->it_index;
2896 return item;
2897 }
2898
2899 Py_DECREF(seq);
2900 it->it_seq = NULL;
2901 return NULL;
2902}
2903
2904static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002905bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002906{
2907 Py_ssize_t len = 0;
2908 if (it->it_seq)
2909 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2910 return PyLong_FromSsize_t(len);
2911}
2912
2913PyDoc_STRVAR(length_hint_doc,
2914 "Private method returning an estimate of len(list(it)).");
2915
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002916static PyMethodDef bytearrayiter_methods[] = {
2917 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002918 length_hint_doc},
2919 {NULL, NULL} /* sentinel */
2920};
2921
2922PyTypeObject PyByteArrayIter_Type = {
2923 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2924 "bytearray_iterator", /* tp_name */
2925 sizeof(bytesiterobject), /* tp_basicsize */
2926 0, /* tp_itemsize */
2927 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002928 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002929 0, /* tp_print */
2930 0, /* tp_getattr */
2931 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002932 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002933 0, /* tp_repr */
2934 0, /* tp_as_number */
2935 0, /* tp_as_sequence */
2936 0, /* tp_as_mapping */
2937 0, /* tp_hash */
2938 0, /* tp_call */
2939 0, /* tp_str */
2940 PyObject_GenericGetAttr, /* tp_getattro */
2941 0, /* tp_setattro */
2942 0, /* tp_as_buffer */
2943 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2944 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002945 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002946 0, /* tp_clear */
2947 0, /* tp_richcompare */
2948 0, /* tp_weaklistoffset */
2949 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002950 (iternextfunc)bytearrayiter_next, /* tp_iternext */
2951 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002952 0,
2953};
2954
2955static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002956bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002957{
2958 bytesiterobject *it;
2959
2960 if (!PyByteArray_Check(seq)) {
2961 PyErr_BadInternalCall();
2962 return NULL;
2963 }
2964 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
2965 if (it == NULL)
2966 return NULL;
2967 it->it_index = 0;
2968 Py_INCREF(seq);
2969 it->it_seq = (PyByteArrayObject *)seq;
2970 _PyObject_GC_TRACK(it);
2971 return (PyObject *)it;
2972}