blob: 165ccae9f423740800d399638dfe3212016f45d5 [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 Peterson9c0e94f2010-04-16 23:00:53 +0000760 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000761 }
762 else if (count < 0) {
763 PyErr_SetString(PyExc_ValueError, "negative count");
764 return -1;
765 }
766 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000767 if (count > 0) {
768 if (PyByteArray_Resize((PyObject *)self, count))
769 return -1;
770 memset(self->ob_bytes, 0, count);
771 }
772 return 0;
773 }
774
775 /* Use the buffer API */
776 if (PyObject_CheckBuffer(arg)) {
777 Py_ssize_t size;
778 Py_buffer view;
779 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
780 return -1;
781 size = view.len;
782 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
783 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
784 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000785 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000786 return 0;
787 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000788 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000789 return -1;
790 }
791
792 /* XXX Optimize this if the arguments is a list, tuple */
793
794 /* Get the iterator */
795 it = PyObject_GetIter(arg);
796 if (it == NULL)
797 return -1;
798 iternext = *Py_TYPE(it)->tp_iternext;
799
800 /* Run the iterator to exhaustion */
801 for (;;) {
802 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000803 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000804
805 /* Get the next item */
806 item = iternext(it);
807 if (item == NULL) {
808 if (PyErr_Occurred()) {
809 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
810 goto error;
811 PyErr_Clear();
812 }
813 break;
814 }
815
816 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000817 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000818 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000819 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000820 goto error;
821
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000822 /* Append the byte */
823 if (Py_SIZE(self) < self->ob_alloc)
824 Py_SIZE(self)++;
825 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
826 goto error;
827 self->ob_bytes[Py_SIZE(self)-1] = value;
828 }
829
830 /* Clean up and return success */
831 Py_DECREF(it);
832 return 0;
833
834 error:
835 /* Error handling when it != NULL */
836 Py_DECREF(it);
837 return -1;
838}
839
840/* Mostly copied from string_repr, but without the
841 "smart quote" functionality. */
842static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000843bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000844{
845 static const char *hexdigits = "0123456789abcdef";
846 const char *quote_prefix = "bytearray(b";
847 const char *quote_postfix = ")";
848 Py_ssize_t length = Py_SIZE(self);
849 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000850 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000851 PyObject *v;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000852 if (length > (PY_SSIZE_T_MAX - 14) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000853 PyErr_SetString(PyExc_OverflowError,
854 "bytearray object is too large to make repr");
855 return NULL;
856 }
Mark Dickinson66f575b2010-02-14 12:53:32 +0000857 newsize = 14 + 4 * length;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000858 v = PyUnicode_FromUnicode(NULL, newsize);
859 if (v == NULL) {
860 return NULL;
861 }
862 else {
863 register Py_ssize_t i;
864 register Py_UNICODE c;
865 register Py_UNICODE *p;
866 int quote;
867
868 /* Figure out which quote to use; single is preferred */
869 quote = '\'';
870 {
871 char *test, *start;
872 start = PyByteArray_AS_STRING(self);
873 for (test = start; test < start+length; ++test) {
874 if (*test == '"') {
875 quote = '\''; /* back to single */
876 goto decided;
877 }
878 else if (*test == '\'')
879 quote = '"';
880 }
881 decided:
882 ;
883 }
884
885 p = PyUnicode_AS_UNICODE(v);
886 while (*quote_prefix)
887 *p++ = *quote_prefix++;
888 *p++ = quote;
889
890 for (i = 0; i < length; i++) {
891 /* There's at least enough room for a hex escape
892 and a closing quote. */
893 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5);
894 c = self->ob_bytes[i];
895 if (c == '\'' || c == '\\')
896 *p++ = '\\', *p++ = c;
897 else if (c == '\t')
898 *p++ = '\\', *p++ = 't';
899 else if (c == '\n')
900 *p++ = '\\', *p++ = 'n';
901 else if (c == '\r')
902 *p++ = '\\', *p++ = 'r';
903 else if (c == 0)
904 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
905 else if (c < ' ' || c >= 0x7f) {
906 *p++ = '\\';
907 *p++ = 'x';
908 *p++ = hexdigits[(c & 0xf0) >> 4];
909 *p++ = hexdigits[c & 0xf];
910 }
911 else
912 *p++ = c;
913 }
914 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1);
915 *p++ = quote;
916 while (*quote_postfix) {
917 *p++ = *quote_postfix++;
918 }
919 *p = '\0';
920 if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
921 Py_DECREF(v);
922 return NULL;
923 }
924 return v;
925 }
926}
927
928static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000929bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000930{
931 if (Py_BytesWarningFlag) {
932 if (PyErr_WarnEx(PyExc_BytesWarning,
933 "str() on a bytearray instance", 1))
934 return NULL;
935 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000936 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000937}
938
939static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000940bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000941{
942 Py_ssize_t self_size, other_size;
943 Py_buffer self_bytes, other_bytes;
944 PyObject *res;
945 Py_ssize_t minsize;
946 int cmp;
947
948 /* Bytes can be compared to anything that supports the (binary)
949 buffer API. Except that a comparison with Unicode is always an
950 error, even if the comparison is for equality. */
951 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
952 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000953 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000954 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000955 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000956 return NULL;
957 }
958
959 Py_INCREF(Py_NotImplemented);
960 return Py_NotImplemented;
961 }
962
963 self_size = _getbuffer(self, &self_bytes);
964 if (self_size < 0) {
965 PyErr_Clear();
966 Py_INCREF(Py_NotImplemented);
967 return Py_NotImplemented;
968 }
969
970 other_size = _getbuffer(other, &other_bytes);
971 if (other_size < 0) {
972 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +0000973 PyBuffer_Release(&self_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000974 Py_INCREF(Py_NotImplemented);
975 return Py_NotImplemented;
976 }
977
978 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
979 /* Shortcut: if the lengths differ, the objects differ */
980 cmp = (op == Py_NE);
981 }
982 else {
983 minsize = self_size;
984 if (other_size < minsize)
985 minsize = other_size;
986
987 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
988 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
989
990 if (cmp == 0) {
991 if (self_size < other_size)
992 cmp = -1;
993 else if (self_size > other_size)
994 cmp = 1;
995 }
996
997 switch (op) {
998 case Py_LT: cmp = cmp < 0; break;
999 case Py_LE: cmp = cmp <= 0; break;
1000 case Py_EQ: cmp = cmp == 0; break;
1001 case Py_NE: cmp = cmp != 0; break;
1002 case Py_GT: cmp = cmp > 0; break;
1003 case Py_GE: cmp = cmp >= 0; break;
1004 }
1005 }
1006
1007 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001008 PyBuffer_Release(&self_bytes);
1009 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001010 Py_INCREF(res);
1011 return res;
1012}
1013
1014static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001015bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001016{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001017 if (self->ob_exports > 0) {
1018 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001019 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001020 PyErr_Print();
1021 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001022 if (self->ob_bytes != 0) {
1023 PyMem_Free(self->ob_bytes);
1024 }
1025 Py_TYPE(self)->tp_free((PyObject *)self);
1026}
1027
1028
1029/* -------------------------------------------------------------------- */
1030/* Methods */
1031
1032#define STRINGLIB_CHAR char
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001033#define STRINGLIB_LEN PyByteArray_GET_SIZE
1034#define STRINGLIB_STR PyByteArray_AS_STRING
1035#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001036#define STRINGLIB_ISSPACE Py_ISSPACE
1037#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001038#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1039#define STRINGLIB_MUTABLE 1
1040
1041#include "stringlib/fastsearch.h"
1042#include "stringlib/count.h"
1043#include "stringlib/find.h"
1044#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001045#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001046#include "stringlib/ctype.h"
1047#include "stringlib/transmogrify.h"
1048
1049
1050/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1051were copied from the old char* style string object. */
1052
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001053/* helper macro to fixup start/end slice values */
1054#define ADJUST_INDICES(start, end, len) \
1055 if (end > len) \
1056 end = len; \
1057 else if (end < 0) { \
1058 end += len; \
1059 if (end < 0) \
1060 end = 0; \
1061 } \
1062 if (start < 0) { \
1063 start += len; \
1064 if (start < 0) \
1065 start = 0; \
1066 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001067
1068Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001069bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001070{
1071 PyObject *subobj;
1072 Py_buffer subbuf;
1073 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1074 Py_ssize_t res;
1075
1076 if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
1077 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1078 return -2;
1079 if (_getbuffer(subobj, &subbuf) < 0)
1080 return -2;
1081 if (dir > 0)
1082 res = stringlib_find_slice(
1083 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1084 subbuf.buf, subbuf.len, start, end);
1085 else
1086 res = stringlib_rfind_slice(
1087 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1088 subbuf.buf, subbuf.len, start, end);
Martin v. Löwis423be952008-08-13 15:53:07 +00001089 PyBuffer_Release(&subbuf);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001090 return res;
1091}
1092
1093PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001094"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001095\n\
1096Return the lowest index in B where subsection sub is found,\n\
1097such that sub is contained within s[start,end]. Optional\n\
1098arguments start and end are interpreted as in slice notation.\n\
1099\n\
1100Return -1 on failure.");
1101
1102static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001103bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001104{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001105 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001106 if (result == -2)
1107 return NULL;
1108 return PyLong_FromSsize_t(result);
1109}
1110
1111PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001112"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001113\n\
1114Return the number of non-overlapping occurrences of subsection sub in\n\
1115bytes B[start:end]. Optional arguments start and end are interpreted\n\
1116as in slice notation.");
1117
1118static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001119bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001120{
1121 PyObject *sub_obj;
1122 const char *str = PyByteArray_AS_STRING(self);
1123 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1124 Py_buffer vsub;
1125 PyObject *count_obj;
1126
1127 if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1128 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1129 return NULL;
1130
1131 if (_getbuffer(sub_obj, &vsub) < 0)
1132 return NULL;
1133
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001134 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001135
1136 count_obj = PyLong_FromSsize_t(
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001137 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001138 );
Martin v. Löwis423be952008-08-13 15:53:07 +00001139 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001140 return count_obj;
1141}
1142
1143
1144PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001145"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001146\n\
1147Like B.find() but raise ValueError when the subsection is not found.");
1148
1149static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001150bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001151{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001152 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001153 if (result == -2)
1154 return NULL;
1155 if (result == -1) {
1156 PyErr_SetString(PyExc_ValueError,
1157 "subsection not found");
1158 return NULL;
1159 }
1160 return PyLong_FromSsize_t(result);
1161}
1162
1163
1164PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001165"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001166\n\
1167Return the highest index in B where subsection sub is found,\n\
1168such that sub is contained within s[start,end]. Optional\n\
1169arguments start and end are interpreted as in slice notation.\n\
1170\n\
1171Return -1 on failure.");
1172
1173static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001174bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001175{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001176 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001177 if (result == -2)
1178 return NULL;
1179 return PyLong_FromSsize_t(result);
1180}
1181
1182
1183PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001184"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001185\n\
1186Like B.rfind() but raise ValueError when the subsection is not found.");
1187
1188static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001189bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001190{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001191 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001192 if (result == -2)
1193 return NULL;
1194 if (result == -1) {
1195 PyErr_SetString(PyExc_ValueError,
1196 "subsection not found");
1197 return NULL;
1198 }
1199 return PyLong_FromSsize_t(result);
1200}
1201
1202
1203static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001204bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001205{
1206 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1207 if (ival == -1 && PyErr_Occurred()) {
1208 Py_buffer varg;
1209 int pos;
1210 PyErr_Clear();
1211 if (_getbuffer(arg, &varg) < 0)
1212 return -1;
1213 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1214 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001215 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001216 return pos >= 0;
1217 }
1218 if (ival < 0 || ival >= 256) {
1219 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1220 return -1;
1221 }
1222
1223 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1224}
1225
1226
1227/* Matches the end (direction >= 0) or start (direction < 0) of self
1228 * against substr, using the start and end arguments. Returns
1229 * -1 on error, 0 if not found and 1 if found.
1230 */
1231Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001232_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001233 Py_ssize_t end, int direction)
1234{
1235 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1236 const char* str;
1237 Py_buffer vsubstr;
1238 int rv = 0;
1239
1240 str = PyByteArray_AS_STRING(self);
1241
1242 if (_getbuffer(substr, &vsubstr) < 0)
1243 return -1;
1244
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001245 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001246
1247 if (direction < 0) {
1248 /* startswith */
1249 if (start+vsubstr.len > len) {
1250 goto done;
1251 }
1252 } else {
1253 /* endswith */
1254 if (end-start < vsubstr.len || start > len) {
1255 goto done;
1256 }
1257
1258 if (end-vsubstr.len > start)
1259 start = end - vsubstr.len;
1260 }
1261 if (end-start >= vsubstr.len)
1262 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1263
1264done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001265 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001266 return rv;
1267}
1268
1269
1270PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001271"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001272\n\
1273Return True if B starts with the specified prefix, False otherwise.\n\
1274With optional start, test B beginning at that position.\n\
1275With optional end, stop comparing B at that position.\n\
1276prefix can also be a tuple of strings to try.");
1277
1278static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001279bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001280{
1281 Py_ssize_t start = 0;
1282 Py_ssize_t end = PY_SSIZE_T_MAX;
1283 PyObject *subobj;
1284 int result;
1285
1286 if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
1287 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1288 return NULL;
1289 if (PyTuple_Check(subobj)) {
1290 Py_ssize_t i;
1291 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001292 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001293 PyTuple_GET_ITEM(subobj, i),
1294 start, end, -1);
1295 if (result == -1)
1296 return NULL;
1297 else if (result) {
1298 Py_RETURN_TRUE;
1299 }
1300 }
1301 Py_RETURN_FALSE;
1302 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001303 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001304 if (result == -1)
1305 return NULL;
1306 else
1307 return PyBool_FromLong(result);
1308}
1309
1310PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001311"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001312\n\
1313Return True if B ends with the specified suffix, False otherwise.\n\
1314With optional start, test B beginning at that position.\n\
1315With optional end, stop comparing B at that position.\n\
1316suffix can also be a tuple of strings to try.");
1317
1318static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001319bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001320{
1321 Py_ssize_t start = 0;
1322 Py_ssize_t end = PY_SSIZE_T_MAX;
1323 PyObject *subobj;
1324 int result;
1325
1326 if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
1327 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1328 return NULL;
1329 if (PyTuple_Check(subobj)) {
1330 Py_ssize_t i;
1331 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001332 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001333 PyTuple_GET_ITEM(subobj, i),
1334 start, end, +1);
1335 if (result == -1)
1336 return NULL;
1337 else if (result) {
1338 Py_RETURN_TRUE;
1339 }
1340 }
1341 Py_RETURN_FALSE;
1342 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001343 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001344 if (result == -1)
1345 return NULL;
1346 else
1347 return PyBool_FromLong(result);
1348}
1349
1350
1351PyDoc_STRVAR(translate__doc__,
1352"B.translate(table[, deletechars]) -> bytearray\n\
1353\n\
1354Return a copy of B, where all characters occurring in the\n\
1355optional argument deletechars are removed, and the remaining\n\
1356characters have been mapped through the given translation\n\
1357table, which must be a bytes object of length 256.");
1358
1359static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001360bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001361{
1362 register char *input, *output;
1363 register const char *table;
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001364 register Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001365 PyObject *input_obj = (PyObject*)self;
1366 const char *output_start;
1367 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001368 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001369 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001370 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001371 Py_buffer vtable, vdel;
1372
1373 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1374 &tableobj, &delobj))
1375 return NULL;
1376
Georg Brandlccc47b62008-12-28 11:44:14 +00001377 if (tableobj == Py_None) {
1378 table = NULL;
1379 tableobj = NULL;
1380 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001381 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001382 } else {
1383 if (vtable.len != 256) {
1384 PyErr_SetString(PyExc_ValueError,
1385 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001386 PyBuffer_Release(&vtable);
1387 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001388 }
1389 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001390 }
1391
1392 if (delobj != NULL) {
1393 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001394 if (tableobj != NULL)
1395 PyBuffer_Release(&vtable);
1396 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001397 }
1398 }
1399 else {
1400 vdel.buf = NULL;
1401 vdel.len = 0;
1402 }
1403
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001404 inlen = PyByteArray_GET_SIZE(input_obj);
1405 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1406 if (result == NULL)
1407 goto done;
1408 output_start = output = PyByteArray_AsString(result);
1409 input = PyByteArray_AS_STRING(input_obj);
1410
Georg Brandlccc47b62008-12-28 11:44:14 +00001411 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001412 /* If no deletions are required, use faster code */
1413 for (i = inlen; --i >= 0; ) {
1414 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001415 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001416 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001417 goto done;
1418 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001419
1420 if (table == NULL) {
1421 for (i = 0; i < 256; i++)
1422 trans_table[i] = Py_CHARMASK(i);
1423 } else {
1424 for (i = 0; i < 256; i++)
1425 trans_table[i] = Py_CHARMASK(table[i]);
1426 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001427
1428 for (i = 0; i < vdel.len; i++)
1429 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1430
1431 for (i = inlen; --i >= 0; ) {
1432 c = Py_CHARMASK(*input++);
1433 if (trans_table[c] != -1)
1434 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1435 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001436 }
1437 /* Fix the size of the resulting string */
1438 if (inlen > 0)
1439 PyByteArray_Resize(result, output - output_start);
1440
1441done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001442 if (tableobj != NULL)
1443 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001444 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001445 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001446 return result;
1447}
1448
1449
Georg Brandlabc38772009-04-12 15:51:51 +00001450static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001451bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001452{
1453 return _Py_bytes_maketrans(args);
1454}
1455
1456
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001457/* find and count characters and substrings */
1458
1459#define findchar(target, target_len, c) \
1460 ((char *)memchr((const void *)(target), c, target_len))
1461
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001462
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001463/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001464Py_LOCAL(PyByteArrayObject *)
1465return_self(PyByteArrayObject *self)
1466{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001467 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001468 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1469 PyByteArray_AS_STRING(self),
1470 PyByteArray_GET_SIZE(self));
1471}
1472
1473Py_LOCAL_INLINE(Py_ssize_t)
1474countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1475{
1476 Py_ssize_t count=0;
1477 const char *start=target;
1478 const char *end=target+target_len;
1479
1480 while ( (start=findchar(start, end-start, c)) != NULL ) {
1481 count++;
1482 if (count >= maxcount)
1483 break;
1484 start += 1;
1485 }
1486 return count;
1487}
1488
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001489
1490/* Algorithms for different cases of string replacement */
1491
1492/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1493Py_LOCAL(PyByteArrayObject *)
1494replace_interleave(PyByteArrayObject *self,
1495 const char *to_s, Py_ssize_t to_len,
1496 Py_ssize_t maxcount)
1497{
1498 char *self_s, *result_s;
1499 Py_ssize_t self_len, result_len;
1500 Py_ssize_t count, i, product;
1501 PyByteArrayObject *result;
1502
1503 self_len = PyByteArray_GET_SIZE(self);
1504
1505 /* 1 at the end plus 1 after every character */
1506 count = self_len+1;
1507 if (maxcount < count)
1508 count = maxcount;
1509
1510 /* Check for overflow */
1511 /* result_len = count * to_len + self_len; */
1512 product = count * to_len;
1513 if (product / to_len != count) {
1514 PyErr_SetString(PyExc_OverflowError,
1515 "replace string is too long");
1516 return NULL;
1517 }
1518 result_len = product + self_len;
1519 if (result_len < 0) {
1520 PyErr_SetString(PyExc_OverflowError,
1521 "replace string is too long");
1522 return NULL;
1523 }
1524
1525 if (! (result = (PyByteArrayObject *)
1526 PyByteArray_FromStringAndSize(NULL, result_len)) )
1527 return NULL;
1528
1529 self_s = PyByteArray_AS_STRING(self);
1530 result_s = PyByteArray_AS_STRING(result);
1531
1532 /* TODO: special case single character, which doesn't need memcpy */
1533
1534 /* Lay the first one down (guaranteed this will occur) */
1535 Py_MEMCPY(result_s, to_s, to_len);
1536 result_s += to_len;
1537 count -= 1;
1538
1539 for (i=0; i<count; i++) {
1540 *result_s++ = *self_s++;
1541 Py_MEMCPY(result_s, to_s, to_len);
1542 result_s += to_len;
1543 }
1544
1545 /* Copy the rest of the original string */
1546 Py_MEMCPY(result_s, self_s, self_len-i);
1547
1548 return result;
1549}
1550
1551/* Special case for deleting a single character */
1552/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1553Py_LOCAL(PyByteArrayObject *)
1554replace_delete_single_character(PyByteArrayObject *self,
1555 char from_c, Py_ssize_t maxcount)
1556{
1557 char *self_s, *result_s;
1558 char *start, *next, *end;
1559 Py_ssize_t self_len, result_len;
1560 Py_ssize_t count;
1561 PyByteArrayObject *result;
1562
1563 self_len = PyByteArray_GET_SIZE(self);
1564 self_s = PyByteArray_AS_STRING(self);
1565
1566 count = countchar(self_s, self_len, from_c, maxcount);
1567 if (count == 0) {
1568 return return_self(self);
1569 }
1570
1571 result_len = self_len - count; /* from_len == 1 */
1572 assert(result_len>=0);
1573
1574 if ( (result = (PyByteArrayObject *)
1575 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1576 return NULL;
1577 result_s = PyByteArray_AS_STRING(result);
1578
1579 start = self_s;
1580 end = self_s + self_len;
1581 while (count-- > 0) {
1582 next = findchar(start, end-start, from_c);
1583 if (next == NULL)
1584 break;
1585 Py_MEMCPY(result_s, start, next-start);
1586 result_s += (next-start);
1587 start = next+1;
1588 }
1589 Py_MEMCPY(result_s, start, end-start);
1590
1591 return result;
1592}
1593
1594/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1595
1596Py_LOCAL(PyByteArrayObject *)
1597replace_delete_substring(PyByteArrayObject *self,
1598 const char *from_s, Py_ssize_t from_len,
1599 Py_ssize_t maxcount)
1600{
1601 char *self_s, *result_s;
1602 char *start, *next, *end;
1603 Py_ssize_t self_len, result_len;
1604 Py_ssize_t count, offset;
1605 PyByteArrayObject *result;
1606
1607 self_len = PyByteArray_GET_SIZE(self);
1608 self_s = PyByteArray_AS_STRING(self);
1609
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001610 count = stringlib_count(self_s, self_len,
1611 from_s, from_len,
1612 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001613
1614 if (count == 0) {
1615 /* no matches */
1616 return return_self(self);
1617 }
1618
1619 result_len = self_len - (count * from_len);
1620 assert (result_len>=0);
1621
1622 if ( (result = (PyByteArrayObject *)
1623 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1624 return NULL;
1625
1626 result_s = PyByteArray_AS_STRING(result);
1627
1628 start = self_s;
1629 end = self_s + self_len;
1630 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001631 offset = stringlib_find(start, end-start,
1632 from_s, from_len,
1633 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001634 if (offset == -1)
1635 break;
1636 next = start + offset;
1637
1638 Py_MEMCPY(result_s, start, next-start);
1639
1640 result_s += (next-start);
1641 start = next+from_len;
1642 }
1643 Py_MEMCPY(result_s, start, end-start);
1644 return result;
1645}
1646
1647/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1648Py_LOCAL(PyByteArrayObject *)
1649replace_single_character_in_place(PyByteArrayObject *self,
1650 char from_c, char to_c,
1651 Py_ssize_t maxcount)
1652{
1653 char *self_s, *result_s, *start, *end, *next;
1654 Py_ssize_t self_len;
1655 PyByteArrayObject *result;
1656
1657 /* The result string will be the same size */
1658 self_s = PyByteArray_AS_STRING(self);
1659 self_len = PyByteArray_GET_SIZE(self);
1660
1661 next = findchar(self_s, self_len, from_c);
1662
1663 if (next == NULL) {
1664 /* No matches; return the original bytes */
1665 return return_self(self);
1666 }
1667
1668 /* Need to make a new bytes */
1669 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1670 if (result == NULL)
1671 return NULL;
1672 result_s = PyByteArray_AS_STRING(result);
1673 Py_MEMCPY(result_s, self_s, self_len);
1674
1675 /* change everything in-place, starting with this one */
1676 start = result_s + (next-self_s);
1677 *start = to_c;
1678 start++;
1679 end = result_s + self_len;
1680
1681 while (--maxcount > 0) {
1682 next = findchar(start, end-start, from_c);
1683 if (next == NULL)
1684 break;
1685 *next = to_c;
1686 start = next+1;
1687 }
1688
1689 return result;
1690}
1691
1692/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1693Py_LOCAL(PyByteArrayObject *)
1694replace_substring_in_place(PyByteArrayObject *self,
1695 const char *from_s, Py_ssize_t from_len,
1696 const char *to_s, Py_ssize_t to_len,
1697 Py_ssize_t maxcount)
1698{
1699 char *result_s, *start, *end;
1700 char *self_s;
1701 Py_ssize_t self_len, offset;
1702 PyByteArrayObject *result;
1703
1704 /* The result bytes will be the same size */
1705
1706 self_s = PyByteArray_AS_STRING(self);
1707 self_len = PyByteArray_GET_SIZE(self);
1708
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001709 offset = stringlib_find(self_s, self_len,
1710 from_s, from_len,
1711 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001712 if (offset == -1) {
1713 /* No matches; return the original bytes */
1714 return return_self(self);
1715 }
1716
1717 /* Need to make a new bytes */
1718 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1719 if (result == NULL)
1720 return NULL;
1721 result_s = PyByteArray_AS_STRING(result);
1722 Py_MEMCPY(result_s, self_s, self_len);
1723
1724 /* change everything in-place, starting with this one */
1725 start = result_s + offset;
1726 Py_MEMCPY(start, to_s, from_len);
1727 start += from_len;
1728 end = result_s + self_len;
1729
1730 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001731 offset = stringlib_find(start, end-start,
1732 from_s, from_len,
1733 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001734 if (offset==-1)
1735 break;
1736 Py_MEMCPY(start+offset, to_s, from_len);
1737 start += offset+from_len;
1738 }
1739
1740 return result;
1741}
1742
1743/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1744Py_LOCAL(PyByteArrayObject *)
1745replace_single_character(PyByteArrayObject *self,
1746 char from_c,
1747 const char *to_s, Py_ssize_t to_len,
1748 Py_ssize_t maxcount)
1749{
1750 char *self_s, *result_s;
1751 char *start, *next, *end;
1752 Py_ssize_t self_len, result_len;
1753 Py_ssize_t count, product;
1754 PyByteArrayObject *result;
1755
1756 self_s = PyByteArray_AS_STRING(self);
1757 self_len = PyByteArray_GET_SIZE(self);
1758
1759 count = countchar(self_s, self_len, from_c, maxcount);
1760 if (count == 0) {
1761 /* no matches, return unchanged */
1762 return return_self(self);
1763 }
1764
1765 /* use the difference between current and new, hence the "-1" */
1766 /* result_len = self_len + count * (to_len-1) */
1767 product = count * (to_len-1);
1768 if (product / (to_len-1) != count) {
1769 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1770 return NULL;
1771 }
1772 result_len = self_len + product;
1773 if (result_len < 0) {
1774 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1775 return NULL;
1776 }
1777
1778 if ( (result = (PyByteArrayObject *)
1779 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1780 return NULL;
1781 result_s = PyByteArray_AS_STRING(result);
1782
1783 start = self_s;
1784 end = self_s + self_len;
1785 while (count-- > 0) {
1786 next = findchar(start, end-start, from_c);
1787 if (next == NULL)
1788 break;
1789
1790 if (next == start) {
1791 /* replace with the 'to' */
1792 Py_MEMCPY(result_s, to_s, to_len);
1793 result_s += to_len;
1794 start += 1;
1795 } else {
1796 /* copy the unchanged old then the 'to' */
1797 Py_MEMCPY(result_s, start, next-start);
1798 result_s += (next-start);
1799 Py_MEMCPY(result_s, to_s, to_len);
1800 result_s += to_len;
1801 start = next+1;
1802 }
1803 }
1804 /* Copy the remainder of the remaining bytes */
1805 Py_MEMCPY(result_s, start, end-start);
1806
1807 return result;
1808}
1809
1810/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1811Py_LOCAL(PyByteArrayObject *)
1812replace_substring(PyByteArrayObject *self,
1813 const char *from_s, Py_ssize_t from_len,
1814 const char *to_s, Py_ssize_t to_len,
1815 Py_ssize_t maxcount)
1816{
1817 char *self_s, *result_s;
1818 char *start, *next, *end;
1819 Py_ssize_t self_len, result_len;
1820 Py_ssize_t count, offset, product;
1821 PyByteArrayObject *result;
1822
1823 self_s = PyByteArray_AS_STRING(self);
1824 self_len = PyByteArray_GET_SIZE(self);
1825
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001826 count = stringlib_count(self_s, self_len,
1827 from_s, from_len,
1828 maxcount);
1829
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001830 if (count == 0) {
1831 /* no matches, return unchanged */
1832 return return_self(self);
1833 }
1834
1835 /* Check for overflow */
1836 /* result_len = self_len + count * (to_len-from_len) */
1837 product = count * (to_len-from_len);
1838 if (product / (to_len-from_len) != count) {
1839 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1840 return NULL;
1841 }
1842 result_len = self_len + product;
1843 if (result_len < 0) {
1844 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1845 return NULL;
1846 }
1847
1848 if ( (result = (PyByteArrayObject *)
1849 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1850 return NULL;
1851 result_s = PyByteArray_AS_STRING(result);
1852
1853 start = self_s;
1854 end = self_s + self_len;
1855 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001856 offset = stringlib_find(start, end-start,
1857 from_s, from_len,
1858 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001859 if (offset == -1)
1860 break;
1861 next = start+offset;
1862 if (next == start) {
1863 /* replace with the 'to' */
1864 Py_MEMCPY(result_s, to_s, to_len);
1865 result_s += to_len;
1866 start += from_len;
1867 } else {
1868 /* copy the unchanged old then the 'to' */
1869 Py_MEMCPY(result_s, start, next-start);
1870 result_s += (next-start);
1871 Py_MEMCPY(result_s, to_s, to_len);
1872 result_s += to_len;
1873 start = next+from_len;
1874 }
1875 }
1876 /* Copy the remainder of the remaining bytes */
1877 Py_MEMCPY(result_s, start, end-start);
1878
1879 return result;
1880}
1881
1882
1883Py_LOCAL(PyByteArrayObject *)
1884replace(PyByteArrayObject *self,
1885 const char *from_s, Py_ssize_t from_len,
1886 const char *to_s, Py_ssize_t to_len,
1887 Py_ssize_t maxcount)
1888{
1889 if (maxcount < 0) {
1890 maxcount = PY_SSIZE_T_MAX;
1891 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1892 /* nothing to do; return the original bytes */
1893 return return_self(self);
1894 }
1895
1896 if (maxcount == 0 ||
1897 (from_len == 0 && to_len == 0)) {
1898 /* nothing to do; return the original bytes */
1899 return return_self(self);
1900 }
1901
1902 /* Handle zero-length special cases */
1903
1904 if (from_len == 0) {
1905 /* insert the 'to' bytes everywhere. */
1906 /* >>> "Python".replace("", ".") */
1907 /* '.P.y.t.h.o.n.' */
1908 return replace_interleave(self, to_s, to_len, maxcount);
1909 }
1910
1911 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1912 /* point for an empty self bytes to generate a non-empty bytes */
1913 /* Special case so the remaining code always gets a non-empty bytes */
1914 if (PyByteArray_GET_SIZE(self) == 0) {
1915 return return_self(self);
1916 }
1917
1918 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00001919 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001920 if (from_len == 1) {
1921 return replace_delete_single_character(
1922 self, from_s[0], maxcount);
1923 } else {
1924 return replace_delete_substring(self, from_s, from_len, maxcount);
1925 }
1926 }
1927
1928 /* Handle special case where both bytes have the same length */
1929
1930 if (from_len == to_len) {
1931 if (from_len == 1) {
1932 return replace_single_character_in_place(
1933 self,
1934 from_s[0],
1935 to_s[0],
1936 maxcount);
1937 } else {
1938 return replace_substring_in_place(
1939 self, from_s, from_len, to_s, to_len, maxcount);
1940 }
1941 }
1942
1943 /* Otherwise use the more generic algorithms */
1944 if (from_len == 1) {
1945 return replace_single_character(self, from_s[0],
1946 to_s, to_len, maxcount);
1947 } else {
1948 /* len('from')>=2, len('to')>=1 */
1949 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
1950 }
1951}
1952
1953
1954PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001955"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001956\n\
1957Return a copy of B with all occurrences of subsection\n\
1958old replaced by new. If the optional argument count is\n\
1959given, only the first count occurrences are replaced.");
1960
1961static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001962bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001963{
1964 Py_ssize_t count = -1;
1965 PyObject *from, *to, *res;
1966 Py_buffer vfrom, vto;
1967
1968 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
1969 return NULL;
1970
1971 if (_getbuffer(from, &vfrom) < 0)
1972 return NULL;
1973 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +00001974 PyBuffer_Release(&vfrom);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001975 return NULL;
1976 }
1977
1978 res = (PyObject *)replace((PyByteArrayObject *) self,
1979 vfrom.buf, vfrom.len,
1980 vto.buf, vto.len, count);
1981
Martin v. Löwis423be952008-08-13 15:53:07 +00001982 PyBuffer_Release(&vfrom);
1983 PyBuffer_Release(&vto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001984 return res;
1985}
1986
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001987PyDoc_STRVAR(split__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001988"B.split([sep[, maxsplit]]) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001989\n\
1990Return a list of the sections in B, using sep as the delimiter.\n\
1991If sep is not given, B is split on ASCII whitespace characters\n\
1992(space, tab, return, newline, formfeed, vertical tab).\n\
1993If maxsplit is given, at most maxsplit splits are done.");
1994
1995static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001996bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001997{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001998 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1999 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002000 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002001 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002002 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002003
2004 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2005 return NULL;
2006 if (maxsplit < 0)
2007 maxsplit = PY_SSIZE_T_MAX;
2008
2009 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002010 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002011
2012 if (_getbuffer(subobj, &vsub) < 0)
2013 return NULL;
2014 sub = vsub.buf;
2015 n = vsub.len;
2016
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002017 list = stringlib_split(
2018 (PyObject*) self, s, len, sub, n, maxsplit
2019 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002020 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002021 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002022}
2023
2024PyDoc_STRVAR(partition__doc__,
2025"B.partition(sep) -> (head, sep, tail)\n\
2026\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002027Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002028the separator itself, and the part after it. If the separator is not\n\
2029found, returns B and two empty bytearray objects.");
2030
2031static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002032bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002033{
2034 PyObject *bytesep, *result;
2035
2036 bytesep = PyByteArray_FromObject(sep_obj);
2037 if (! bytesep)
2038 return NULL;
2039
2040 result = stringlib_partition(
2041 (PyObject*) self,
2042 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2043 bytesep,
2044 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2045 );
2046
2047 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002048 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002049}
2050
2051PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002052"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002053\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002054Search for the separator sep in B, starting at the end of B,\n\
2055and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002056part after it. If the separator is not found, returns two empty\n\
2057bytearray objects and B.");
2058
2059static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002060bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002061{
2062 PyObject *bytesep, *result;
2063
2064 bytesep = PyByteArray_FromObject(sep_obj);
2065 if (! bytesep)
2066 return NULL;
2067
2068 result = stringlib_rpartition(
2069 (PyObject*) self,
2070 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2071 bytesep,
2072 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2073 );
2074
2075 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002076 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002077}
2078
2079PyDoc_STRVAR(rsplit__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002080"B.rsplit(sep[, maxsplit]) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002081\n\
2082Return a list of the sections in B, using sep as the delimiter,\n\
2083starting at the end of B and working to the front.\n\
2084If sep is not given, B is split on ASCII whitespace characters\n\
2085(space, tab, return, newline, formfeed, vertical tab).\n\
2086If maxsplit is given, at most maxsplit splits are done.");
2087
2088static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002089bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002090{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002091 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2092 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002093 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002094 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002095 Py_buffer vsub;
2096
2097 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2098 return NULL;
2099 if (maxsplit < 0)
2100 maxsplit = PY_SSIZE_T_MAX;
2101
2102 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002103 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002104
2105 if (_getbuffer(subobj, &vsub) < 0)
2106 return NULL;
2107 sub = vsub.buf;
2108 n = vsub.len;
2109
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002110 list = stringlib_rsplit(
2111 (PyObject*) self, s, len, sub, n, maxsplit
2112 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002113 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002114 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002115}
2116
2117PyDoc_STRVAR(reverse__doc__,
2118"B.reverse() -> None\n\
2119\n\
2120Reverse the order of the values in B in place.");
2121static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002122bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002123{
2124 char swap, *head, *tail;
2125 Py_ssize_t i, j, n = Py_SIZE(self);
2126
2127 j = n / 2;
2128 head = self->ob_bytes;
2129 tail = head + n - 1;
2130 for (i = 0; i < j; i++) {
2131 swap = *head;
2132 *head++ = *tail;
2133 *tail-- = swap;
2134 }
2135
2136 Py_RETURN_NONE;
2137}
2138
2139PyDoc_STRVAR(insert__doc__,
2140"B.insert(index, int) -> None\n\
2141\n\
2142Insert a single item into the bytearray before the given index.");
2143static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002144bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002145{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002146 PyObject *value;
2147 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002148 Py_ssize_t where, n = Py_SIZE(self);
2149
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002150 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002151 return NULL;
2152
2153 if (n == PY_SSIZE_T_MAX) {
2154 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002155 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002156 return NULL;
2157 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002158 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002159 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002160 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2161 return NULL;
2162
2163 if (where < 0) {
2164 where += n;
2165 if (where < 0)
2166 where = 0;
2167 }
2168 if (where > n)
2169 where = n;
2170 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002171 self->ob_bytes[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002172
2173 Py_RETURN_NONE;
2174}
2175
2176PyDoc_STRVAR(append__doc__,
2177"B.append(int) -> None\n\
2178\n\
2179Append a single item to the end of B.");
2180static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002181bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002182{
2183 int value;
2184 Py_ssize_t n = Py_SIZE(self);
2185
2186 if (! _getbytevalue(arg, &value))
2187 return NULL;
2188 if (n == PY_SSIZE_T_MAX) {
2189 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002190 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002191 return NULL;
2192 }
2193 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2194 return NULL;
2195
2196 self->ob_bytes[n] = value;
2197
2198 Py_RETURN_NONE;
2199}
2200
2201PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002202"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002203\n\
2204Append all the elements from the iterator or sequence to the\n\
2205end of B.");
2206static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002207bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002208{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002209 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002210 Py_ssize_t buf_size = 0, len = 0;
2211 int value;
2212 char *buf;
2213
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002214 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002215 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002216 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002217 return NULL;
2218
2219 Py_RETURN_NONE;
2220 }
2221
2222 it = PyObject_GetIter(arg);
2223 if (it == NULL)
2224 return NULL;
2225
2226 /* Try to determine the length of the argument. 32 is abitrary. */
2227 buf_size = _PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002228 if (buf_size == -1) {
2229 Py_DECREF(it);
2230 return NULL;
2231 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002232
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002233 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2234 if (bytearray_obj == NULL)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002235 return NULL;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002236 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002237
2238 while ((item = PyIter_Next(it)) != NULL) {
2239 if (! _getbytevalue(item, &value)) {
2240 Py_DECREF(item);
2241 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002242 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002243 return NULL;
2244 }
2245 buf[len++] = value;
2246 Py_DECREF(item);
2247
2248 if (len >= buf_size) {
2249 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002250 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002251 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002252 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002253 return NULL;
2254 }
2255 /* Recompute the `buf' pointer, since the resizing operation may
2256 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002257 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002258 }
2259 }
2260 Py_DECREF(it);
2261
2262 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002263 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2264 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002265 return NULL;
2266 }
2267
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002268 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002269 return NULL;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002270 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002271
2272 Py_RETURN_NONE;
2273}
2274
2275PyDoc_STRVAR(pop__doc__,
2276"B.pop([index]) -> int\n\
2277\n\
2278Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002279argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002280static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002281bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002282{
2283 int value;
2284 Py_ssize_t where = -1, n = Py_SIZE(self);
2285
2286 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2287 return NULL;
2288
2289 if (n == 0) {
2290 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002291 "cannot pop an empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002292 return NULL;
2293 }
2294 if (where < 0)
2295 where += Py_SIZE(self);
2296 if (where < 0 || where >= Py_SIZE(self)) {
2297 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2298 return NULL;
2299 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002300 if (!_canresize(self))
2301 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002302
2303 value = self->ob_bytes[where];
2304 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2305 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2306 return NULL;
2307
Mark Dickinson54a3db92009-09-06 10:19:23 +00002308 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002309}
2310
2311PyDoc_STRVAR(remove__doc__,
2312"B.remove(int) -> None\n\
2313\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002314Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002315static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002316bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002317{
2318 int value;
2319 Py_ssize_t where, n = Py_SIZE(self);
2320
2321 if (! _getbytevalue(arg, &value))
2322 return NULL;
2323
2324 for (where = 0; where < n; where++) {
2325 if (self->ob_bytes[where] == value)
2326 break;
2327 }
2328 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002329 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002330 return NULL;
2331 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002332 if (!_canresize(self))
2333 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002334
2335 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2336 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2337 return NULL;
2338
2339 Py_RETURN_NONE;
2340}
2341
2342/* XXX These two helpers could be optimized if argsize == 1 */
2343
2344static Py_ssize_t
2345lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2346 void *argptr, Py_ssize_t argsize)
2347{
2348 Py_ssize_t i = 0;
2349 while (i < mysize && memchr(argptr, myptr[i], argsize))
2350 i++;
2351 return i;
2352}
2353
2354static Py_ssize_t
2355rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2356 void *argptr, Py_ssize_t argsize)
2357{
2358 Py_ssize_t i = mysize - 1;
2359 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2360 i--;
2361 return i + 1;
2362}
2363
2364PyDoc_STRVAR(strip__doc__,
2365"B.strip([bytes]) -> bytearray\n\
2366\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002367Strip leading and trailing bytes contained in the argument\n\
2368and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002369If the argument is omitted, strip ASCII whitespace.");
2370static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002371bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002372{
2373 Py_ssize_t left, right, mysize, argsize;
2374 void *myptr, *argptr;
2375 PyObject *arg = Py_None;
2376 Py_buffer varg;
2377 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2378 return NULL;
2379 if (arg == Py_None) {
2380 argptr = "\t\n\r\f\v ";
2381 argsize = 6;
2382 }
2383 else {
2384 if (_getbuffer(arg, &varg) < 0)
2385 return NULL;
2386 argptr = varg.buf;
2387 argsize = varg.len;
2388 }
2389 myptr = self->ob_bytes;
2390 mysize = Py_SIZE(self);
2391 left = lstrip_helper(myptr, mysize, argptr, argsize);
2392 if (left == mysize)
2393 right = left;
2394 else
2395 right = rstrip_helper(myptr, mysize, argptr, argsize);
2396 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002397 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002398 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2399}
2400
2401PyDoc_STRVAR(lstrip__doc__,
2402"B.lstrip([bytes]) -> bytearray\n\
2403\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002404Strip leading bytes contained in the argument\n\
2405and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002406If the argument is omitted, strip leading ASCII whitespace.");
2407static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002408bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002409{
2410 Py_ssize_t left, right, mysize, argsize;
2411 void *myptr, *argptr;
2412 PyObject *arg = Py_None;
2413 Py_buffer varg;
2414 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2415 return NULL;
2416 if (arg == Py_None) {
2417 argptr = "\t\n\r\f\v ";
2418 argsize = 6;
2419 }
2420 else {
2421 if (_getbuffer(arg, &varg) < 0)
2422 return NULL;
2423 argptr = varg.buf;
2424 argsize = varg.len;
2425 }
2426 myptr = self->ob_bytes;
2427 mysize = Py_SIZE(self);
2428 left = lstrip_helper(myptr, mysize, argptr, argsize);
2429 right = mysize;
2430 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002431 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002432 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2433}
2434
2435PyDoc_STRVAR(rstrip__doc__,
2436"B.rstrip([bytes]) -> bytearray\n\
2437\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002438Strip trailing bytes contained in the argument\n\
2439and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002440If the argument is omitted, strip trailing ASCII whitespace.");
2441static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002442bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002443{
2444 Py_ssize_t left, right, mysize, argsize;
2445 void *myptr, *argptr;
2446 PyObject *arg = Py_None;
2447 Py_buffer varg;
2448 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2449 return NULL;
2450 if (arg == Py_None) {
2451 argptr = "\t\n\r\f\v ";
2452 argsize = 6;
2453 }
2454 else {
2455 if (_getbuffer(arg, &varg) < 0)
2456 return NULL;
2457 argptr = varg.buf;
2458 argsize = varg.len;
2459 }
2460 myptr = self->ob_bytes;
2461 mysize = Py_SIZE(self);
2462 left = 0;
2463 right = rstrip_helper(myptr, mysize, argptr, argsize);
2464 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002465 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002466 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2467}
2468
2469PyDoc_STRVAR(decode_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002470"B.decode([encoding[, errors]]) -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002471\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002472Decode B using the codec registered for encoding. encoding defaults\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002473to the default encoding. errors may be given to set a different error\n\
2474handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2475a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2476as well as any other name registered with codecs.register_error that is\n\
2477able to handle UnicodeDecodeErrors.");
2478
2479static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002480bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002481{
2482 const char *encoding = NULL;
2483 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002484 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002485
Benjamin Peterson308d6372009-09-18 21:42:35 +00002486 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002487 return NULL;
2488 if (encoding == NULL)
2489 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002490 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002491}
2492
2493PyDoc_STRVAR(alloc_doc,
2494"B.__alloc__() -> int\n\
2495\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002496Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002497
2498static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002499bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002500{
2501 return PyLong_FromSsize_t(self->ob_alloc);
2502}
2503
2504PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002505"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002506\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002507Concatenate any number of bytes/bytearray objects, with B\n\
2508in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002509
2510static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002511bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002512{
2513 PyObject *seq;
2514 Py_ssize_t mysize = Py_SIZE(self);
2515 Py_ssize_t i;
2516 Py_ssize_t n;
2517 PyObject **items;
2518 Py_ssize_t totalsize = 0;
2519 PyObject *result;
2520 char *dest;
2521
2522 seq = PySequence_Fast(it, "can only join an iterable");
2523 if (seq == NULL)
2524 return NULL;
2525 n = PySequence_Fast_GET_SIZE(seq);
2526 items = PySequence_Fast_ITEMS(seq);
2527
2528 /* Compute the total size, and check that they are all bytes */
2529 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2530 for (i = 0; i < n; i++) {
2531 PyObject *obj = items[i];
2532 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2533 PyErr_Format(PyExc_TypeError,
2534 "can only join an iterable of bytes "
2535 "(item %ld has type '%.100s')",
2536 /* XXX %ld isn't right on Win64 */
2537 (long)i, Py_TYPE(obj)->tp_name);
2538 goto error;
2539 }
2540 if (i > 0)
2541 totalsize += mysize;
2542 totalsize += Py_SIZE(obj);
2543 if (totalsize < 0) {
2544 PyErr_NoMemory();
2545 goto error;
2546 }
2547 }
2548
2549 /* Allocate the result, and copy the bytes */
2550 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2551 if (result == NULL)
2552 goto error;
2553 dest = PyByteArray_AS_STRING(result);
2554 for (i = 0; i < n; i++) {
2555 PyObject *obj = items[i];
2556 Py_ssize_t size = Py_SIZE(obj);
2557 char *buf;
2558 if (PyByteArray_Check(obj))
2559 buf = PyByteArray_AS_STRING(obj);
2560 else
2561 buf = PyBytes_AS_STRING(obj);
2562 if (i) {
2563 memcpy(dest, self->ob_bytes, mysize);
2564 dest += mysize;
2565 }
2566 memcpy(dest, buf, size);
2567 dest += size;
2568 }
2569
2570 /* Done */
2571 Py_DECREF(seq);
2572 return result;
2573
2574 /* Error handling */
2575 error:
2576 Py_DECREF(seq);
2577 return NULL;
2578}
2579
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002580PyDoc_STRVAR(splitlines__doc__,
2581"B.splitlines([keepends]) -> list of lines\n\
2582\n\
2583Return a list of the lines in B, breaking at line boundaries.\n\
2584Line breaks are not included in the resulting list unless keepends\n\
2585is given and true.");
2586
2587static PyObject*
2588bytearray_splitlines(PyObject *self, PyObject *args)
2589{
2590 int keepends = 0;
2591
2592 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2593 return NULL;
2594
2595 return stringlib_splitlines(
2596 (PyObject*) self, PyByteArray_AS_STRING(self),
2597 PyByteArray_GET_SIZE(self), keepends
2598 );
2599}
2600
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002601PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002602"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002603\n\
2604Create a bytearray object from a string of hexadecimal numbers.\n\
2605Spaces between two numbers are accepted.\n\
2606Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2607
2608static int
2609hex_digit_to_int(Py_UNICODE c)
2610{
2611 if (c >= 128)
2612 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002613 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002614 return c - '0';
2615 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002616 if (Py_ISUPPER(c))
2617 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002618 if (c >= 'a' && c <= 'f')
2619 return c - 'a' + 10;
2620 }
2621 return -1;
2622}
2623
2624static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002625bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002626{
2627 PyObject *newbytes, *hexobj;
2628 char *buf;
2629 Py_UNICODE *hex;
2630 Py_ssize_t hexlen, byteslen, i, j;
2631 int top, bot;
2632
2633 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2634 return NULL;
2635 assert(PyUnicode_Check(hexobj));
2636 hexlen = PyUnicode_GET_SIZE(hexobj);
2637 hex = PyUnicode_AS_UNICODE(hexobj);
2638 byteslen = hexlen/2; /* This overestimates if there are spaces */
2639 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2640 if (!newbytes)
2641 return NULL;
2642 buf = PyByteArray_AS_STRING(newbytes);
2643 for (i = j = 0; i < hexlen; i += 2) {
2644 /* skip over spaces in the input */
2645 while (hex[i] == ' ')
2646 i++;
2647 if (i >= hexlen)
2648 break;
2649 top = hex_digit_to_int(hex[i]);
2650 bot = hex_digit_to_int(hex[i+1]);
2651 if (top == -1 || bot == -1) {
2652 PyErr_Format(PyExc_ValueError,
2653 "non-hexadecimal number found in "
2654 "fromhex() arg at position %zd", i);
2655 goto error;
2656 }
2657 buf[j++] = (top << 4) + bot;
2658 }
2659 if (PyByteArray_Resize(newbytes, j) < 0)
2660 goto error;
2661 return newbytes;
2662
2663 error:
2664 Py_DECREF(newbytes);
2665 return NULL;
2666}
2667
2668PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2669
2670static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002671bytearray_reduce(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002672{
2673 PyObject *latin1, *dict;
2674 if (self->ob_bytes)
2675 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2676 Py_SIZE(self), NULL);
2677 else
2678 latin1 = PyUnicode_FromString("");
2679
2680 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2681 if (dict == NULL) {
2682 PyErr_Clear();
2683 dict = Py_None;
2684 Py_INCREF(dict);
2685 }
2686
2687 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2688}
2689
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002690PyDoc_STRVAR(sizeof_doc,
2691"B.__sizeof__() -> int\n\
2692 \n\
2693Returns the size of B in memory, in bytes");
2694static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002695bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002696{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002697 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002698
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002699 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2700 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002701}
2702
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002703static PySequenceMethods bytearray_as_sequence = {
2704 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002705 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002706 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2707 (ssizeargfunc)bytearray_getitem, /* sq_item */
2708 0, /* sq_slice */
2709 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2710 0, /* sq_ass_slice */
2711 (objobjproc)bytearray_contains, /* sq_contains */
2712 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2713 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002714};
2715
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002716static PyMappingMethods bytearray_as_mapping = {
2717 (lenfunc)bytearray_length,
2718 (binaryfunc)bytearray_subscript,
2719 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002720};
2721
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002722static PyBufferProcs bytearray_as_buffer = {
2723 (getbufferproc)bytearray_getbuffer,
2724 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002725};
2726
2727static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002728bytearray_methods[] = {
2729 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2730 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2731 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2732 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002733 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2734 _Py_capitalize__doc__},
2735 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002736 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002737 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002738 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002739 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2740 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002741 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2742 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2743 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002744 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002745 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2746 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002747 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2748 _Py_isalnum__doc__},
2749 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2750 _Py_isalpha__doc__},
2751 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2752 _Py_isdigit__doc__},
2753 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2754 _Py_islower__doc__},
2755 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2756 _Py_isspace__doc__},
2757 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2758 _Py_istitle__doc__},
2759 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2760 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002761 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002762 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2763 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002764 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2765 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002766 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002767 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2768 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2769 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2770 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2771 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2772 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2773 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002774 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002775 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2776 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2777 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2778 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002779 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002780 splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002781 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002782 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002783 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002784 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2785 _Py_swapcase__doc__},
2786 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002787 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002788 translate__doc__},
2789 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2790 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2791 {NULL}
2792};
2793
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002794PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002795"bytearray(iterable_of_ints) -> bytearray\n\
2796bytearray(string, encoding[, errors]) -> bytearray\n\
2797bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray\n\
2798bytearray(memory_view) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002799\n\
2800Construct an mutable bytearray object from:\n\
2801 - an iterable yielding integers in range(256)\n\
2802 - a text string encoded using the specified encoding\n\
2803 - a bytes or a bytearray object\n\
2804 - any object implementing the buffer API.\n\
2805\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002806bytearray(int) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002807\n\
2808Construct a zero-initialized bytearray of the given length.");
2809
2810
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002811static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002812
2813PyTypeObject PyByteArray_Type = {
2814 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2815 "bytearray",
2816 sizeof(PyByteArrayObject),
2817 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002818 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002819 0, /* tp_print */
2820 0, /* tp_getattr */
2821 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002822 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002823 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002824 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002825 &bytearray_as_sequence, /* tp_as_sequence */
2826 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002827 0, /* tp_hash */
2828 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002829 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002830 PyObject_GenericGetAttr, /* tp_getattro */
2831 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002832 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002833 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002834 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002835 0, /* tp_traverse */
2836 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002837 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002838 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002839 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002840 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002841 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002842 0, /* tp_members */
2843 0, /* tp_getset */
2844 0, /* tp_base */
2845 0, /* tp_dict */
2846 0, /* tp_descr_get */
2847 0, /* tp_descr_set */
2848 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002849 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002850 PyType_GenericAlloc, /* tp_alloc */
2851 PyType_GenericNew, /* tp_new */
2852 PyObject_Del, /* tp_free */
2853};
2854
2855/*********************** Bytes Iterator ****************************/
2856
2857typedef struct {
2858 PyObject_HEAD
2859 Py_ssize_t it_index;
2860 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2861} bytesiterobject;
2862
2863static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002864bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002865{
2866 _PyObject_GC_UNTRACK(it);
2867 Py_XDECREF(it->it_seq);
2868 PyObject_GC_Del(it);
2869}
2870
2871static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002872bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002873{
2874 Py_VISIT(it->it_seq);
2875 return 0;
2876}
2877
2878static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002879bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002880{
2881 PyByteArrayObject *seq;
2882 PyObject *item;
2883
2884 assert(it != NULL);
2885 seq = it->it_seq;
2886 if (seq == NULL)
2887 return NULL;
2888 assert(PyByteArray_Check(seq));
2889
2890 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2891 item = PyLong_FromLong(
2892 (unsigned char)seq->ob_bytes[it->it_index]);
2893 if (item != NULL)
2894 ++it->it_index;
2895 return item;
2896 }
2897
2898 Py_DECREF(seq);
2899 it->it_seq = NULL;
2900 return NULL;
2901}
2902
2903static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002904bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002905{
2906 Py_ssize_t len = 0;
2907 if (it->it_seq)
2908 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2909 return PyLong_FromSsize_t(len);
2910}
2911
2912PyDoc_STRVAR(length_hint_doc,
2913 "Private method returning an estimate of len(list(it)).");
2914
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002915static PyMethodDef bytearrayiter_methods[] = {
2916 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002917 length_hint_doc},
2918 {NULL, NULL} /* sentinel */
2919};
2920
2921PyTypeObject PyByteArrayIter_Type = {
2922 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2923 "bytearray_iterator", /* tp_name */
2924 sizeof(bytesiterobject), /* tp_basicsize */
2925 0, /* tp_itemsize */
2926 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002927 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002928 0, /* tp_print */
2929 0, /* tp_getattr */
2930 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002931 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002932 0, /* tp_repr */
2933 0, /* tp_as_number */
2934 0, /* tp_as_sequence */
2935 0, /* tp_as_mapping */
2936 0, /* tp_hash */
2937 0, /* tp_call */
2938 0, /* tp_str */
2939 PyObject_GenericGetAttr, /* tp_getattro */
2940 0, /* tp_setattro */
2941 0, /* tp_as_buffer */
2942 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2943 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002944 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002945 0, /* tp_clear */
2946 0, /* tp_richcompare */
2947 0, /* tp_weaklistoffset */
2948 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002949 (iternextfunc)bytearrayiter_next, /* tp_iternext */
2950 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002951 0,
2952};
2953
2954static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002955bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002956{
2957 bytesiterobject *it;
2958
2959 if (!PyByteArray_Check(seq)) {
2960 PyErr_BadInternalCall();
2961 return NULL;
2962 }
2963 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
2964 if (it == NULL)
2965 return NULL;
2966 it->it_index = 0;
2967 Py_INCREF(seq);
2968 it->it_seq = (PyByteArrayObject *)seq;
2969 _PyObject_GC_TRACK(it);
2970 return (PyObject *)it;
2971}