blob: 39aa69a40492d7213735bdd87b3f28c4ef35a5b6 [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
8static PyByteArrayObject *nullbytes = NULL;
Antoine Pitrou20d6c152010-01-17 12:43:00 +00009char _PyByteArray_empty_string[] = "";
Christian Heimes2c9c7a52008-05-26 13:42:13 +000010
11void
12PyByteArray_Fini(void)
13{
14 Py_CLEAR(nullbytes);
15}
16
17int
18PyByteArray_Init(void)
19{
20 nullbytes = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
21 if (nullbytes == NULL)
22 return 0;
23 nullbytes->ob_bytes = NULL;
24 Py_SIZE(nullbytes) = nullbytes->ob_alloc = 0;
25 nullbytes->ob_exports = 0;
26 return 1;
27}
28
29/* end nullbytes support */
30
31/* Helpers */
32
33static int
34_getbytevalue(PyObject* arg, int *value)
35{
36 long face_value;
37
38 if (PyLong_Check(arg)) {
39 face_value = PyLong_AsLong(arg);
Georg Brandl9a54d7c2008-07-16 23:15:30 +000040 } else {
41 PyObject *index = PyNumber_Index(arg);
42 if (index == NULL) {
43 PyErr_Format(PyExc_TypeError, "an integer is required");
Christian Heimes2c9c7a52008-05-26 13:42:13 +000044 return 0;
45 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +000046 face_value = PyLong_AsLong(index);
47 Py_DECREF(index);
48 }
49
50 if (face_value < 0 || face_value >= 256) {
51 /* this includes the OverflowError in case the long is too large */
52 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Christian Heimes2c9c7a52008-05-26 13:42:13 +000053 return 0;
54 }
55
56 *value = face_value;
57 return 1;
58}
59
60static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +000061bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000062{
63 int ret;
64 void *ptr;
65 if (view == NULL) {
66 obj->ob_exports++;
67 return 0;
68 }
Antoine Pitrou20d6c152010-01-17 12:43:00 +000069 ptr = (void *) PyByteArray_AS_STRING(obj);
Martin v. Löwis423be952008-08-13 15:53:07 +000070 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
Christian Heimes2c9c7a52008-05-26 13:42:13 +000071 if (ret >= 0) {
72 obj->ob_exports++;
73 }
74 return ret;
75}
76
77static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +000078bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000079{
80 obj->ob_exports--;
81}
82
83static Py_ssize_t
84_getbuffer(PyObject *obj, Py_buffer *view)
85{
86 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
87
88 if (buffer == NULL || buffer->bf_getbuffer == NULL)
89 {
90 PyErr_Format(PyExc_TypeError,
91 "Type %.100s doesn't support the buffer API",
92 Py_TYPE(obj)->tp_name);
93 return -1;
94 }
95
96 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
97 return -1;
98 return view->len;
99}
100
Antoine Pitrou5504e892008-12-06 21:27:53 +0000101static int
102_canresize(PyByteArrayObject *self)
103{
104 if (self->ob_exports > 0) {
105 PyErr_SetString(PyExc_BufferError,
106 "Existing exports of data: object cannot be re-sized");
107 return 0;
108 }
109 return 1;
110}
111
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000112/* Direct API functions */
113
114PyObject *
115PyByteArray_FromObject(PyObject *input)
116{
117 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
118 input, NULL);
119}
120
121PyObject *
122PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
123{
124 PyByteArrayObject *new;
125 Py_ssize_t alloc;
126
127 if (size < 0) {
128 PyErr_SetString(PyExc_SystemError,
129 "Negative size passed to PyByteArray_FromStringAndSize");
130 return NULL;
131 }
132
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000133 /* Prevent buffer overflow when setting alloc to size+1. */
134 if (size == PY_SSIZE_T_MAX) {
135 return PyErr_NoMemory();
136 }
137
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000138 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
139 if (new == NULL)
140 return NULL;
141
142 if (size == 0) {
143 new->ob_bytes = NULL;
144 alloc = 0;
145 }
146 else {
147 alloc = size + 1;
148 new->ob_bytes = PyMem_Malloc(alloc);
149 if (new->ob_bytes == NULL) {
150 Py_DECREF(new);
151 return PyErr_NoMemory();
152 }
Antoine Pitrou20d6c152010-01-17 12:43:00 +0000153 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000154 memcpy(new->ob_bytes, bytes, size);
155 new->ob_bytes[size] = '\0'; /* Trailing null byte */
156 }
157 Py_SIZE(new) = size;
158 new->ob_alloc = alloc;
159 new->ob_exports = 0;
160
161 return (PyObject *)new;
162}
163
164Py_ssize_t
165PyByteArray_Size(PyObject *self)
166{
167 assert(self != NULL);
168 assert(PyByteArray_Check(self));
169
170 return PyByteArray_GET_SIZE(self);
171}
172
173char *
174PyByteArray_AsString(PyObject *self)
175{
176 assert(self != NULL);
177 assert(PyByteArray_Check(self));
178
179 return PyByteArray_AS_STRING(self);
180}
181
182int
183PyByteArray_Resize(PyObject *self, Py_ssize_t size)
184{
185 void *sval;
186 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
187
188 assert(self != NULL);
189 assert(PyByteArray_Check(self));
190 assert(size >= 0);
191
Antoine Pitrou5504e892008-12-06 21:27:53 +0000192 if (size == Py_SIZE(self)) {
193 return 0;
194 }
195 if (!_canresize((PyByteArrayObject *)self)) {
196 return -1;
197 }
198
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000199 if (size < alloc / 2) {
200 /* Major downsize; resize down to exact size */
201 alloc = size + 1;
202 }
203 else if (size < alloc) {
204 /* Within allocated size; quick exit */
205 Py_SIZE(self) = size;
206 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
207 return 0;
208 }
209 else if (size <= alloc * 1.125) {
210 /* Moderate upsize; overallocate similar to list_resize() */
211 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
212 }
213 else {
214 /* Major upsize; resize up to exact size */
215 alloc = size + 1;
216 }
217
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000218 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
219 if (sval == NULL) {
220 PyErr_NoMemory();
221 return -1;
222 }
223
224 ((PyByteArrayObject *)self)->ob_bytes = sval;
225 Py_SIZE(self) = size;
226 ((PyByteArrayObject *)self)->ob_alloc = alloc;
227 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
228
229 return 0;
230}
231
232PyObject *
233PyByteArray_Concat(PyObject *a, PyObject *b)
234{
235 Py_ssize_t size;
236 Py_buffer va, vb;
237 PyByteArrayObject *result = NULL;
238
239 va.len = -1;
240 vb.len = -1;
241 if (_getbuffer(a, &va) < 0 ||
242 _getbuffer(b, &vb) < 0) {
243 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
244 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
245 goto done;
246 }
247
248 size = va.len + vb.len;
249 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000250 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000251 goto done;
252 }
253
254 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
255 if (result != NULL) {
256 memcpy(result->ob_bytes, va.buf, va.len);
257 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
258 }
259
260 done:
261 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000262 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000263 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000264 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000265 return (PyObject *)result;
266}
267
268/* Functions stuffed into the type object */
269
270static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000271bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000272{
273 return Py_SIZE(self);
274}
275
276static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000277bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000278{
279 Py_ssize_t mysize;
280 Py_ssize_t size;
281 Py_buffer vo;
282
283 if (_getbuffer(other, &vo) < 0) {
284 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
285 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
286 return NULL;
287 }
288
289 mysize = Py_SIZE(self);
290 size = mysize + vo.len;
291 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000292 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000293 return PyErr_NoMemory();
294 }
295 if (size < self->ob_alloc) {
296 Py_SIZE(self) = size;
297 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
298 }
299 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000300 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000301 return NULL;
302 }
303 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000304 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000305 Py_INCREF(self);
306 return (PyObject *)self;
307}
308
309static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000310bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000311{
312 PyByteArrayObject *result;
313 Py_ssize_t mysize;
314 Py_ssize_t size;
315
316 if (count < 0)
317 count = 0;
318 mysize = Py_SIZE(self);
319 size = mysize * count;
320 if (count != 0 && size / count != mysize)
321 return PyErr_NoMemory();
322 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
323 if (result != NULL && size != 0) {
324 if (mysize == 1)
325 memset(result->ob_bytes, self->ob_bytes[0], size);
326 else {
327 Py_ssize_t i;
328 for (i = 0; i < count; i++)
329 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
330 }
331 }
332 return (PyObject *)result;
333}
334
335static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000336bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000337{
338 Py_ssize_t mysize;
339 Py_ssize_t size;
340
341 if (count < 0)
342 count = 0;
343 mysize = Py_SIZE(self);
344 size = mysize * count;
345 if (count != 0 && size / count != mysize)
346 return PyErr_NoMemory();
347 if (size < self->ob_alloc) {
348 Py_SIZE(self) = size;
349 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
350 }
351 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
352 return NULL;
353
354 if (mysize == 1)
355 memset(self->ob_bytes, self->ob_bytes[0], size);
356 else {
357 Py_ssize_t i;
358 for (i = 1; i < count; i++)
359 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
360 }
361
362 Py_INCREF(self);
363 return (PyObject *)self;
364}
365
366static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000367bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000368{
369 if (i < 0)
370 i += Py_SIZE(self);
371 if (i < 0 || i >= Py_SIZE(self)) {
372 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
373 return NULL;
374 }
375 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
376}
377
378static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000379bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000380{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000381 if (PyIndex_Check(index)) {
382 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000383
384 if (i == -1 && PyErr_Occurred())
385 return NULL;
386
387 if (i < 0)
388 i += PyByteArray_GET_SIZE(self);
389
390 if (i < 0 || i >= Py_SIZE(self)) {
391 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
392 return NULL;
393 }
394 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
395 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000396 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000397 Py_ssize_t start, stop, step, slicelength, cur, i;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000398 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000399 PyByteArray_GET_SIZE(self),
400 &start, &stop, &step, &slicelength) < 0) {
401 return NULL;
402 }
403
404 if (slicelength <= 0)
405 return PyByteArray_FromStringAndSize("", 0);
406 else if (step == 1) {
407 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
408 slicelength);
409 }
410 else {
411 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000412 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000413 PyObject *result;
414
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000415 result = PyByteArray_FromStringAndSize(NULL, slicelength);
416 if (result == NULL)
417 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000418
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000419 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000420 for (cur = start, i = 0; i < slicelength;
421 cur += step, i++) {
422 result_buf[i] = source_buf[cur];
423 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000424 return result;
425 }
426 }
427 else {
428 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
429 return NULL;
430 }
431}
432
433static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000434bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000435 PyObject *values)
436{
437 Py_ssize_t avail, needed;
438 void *bytes;
439 Py_buffer vbytes;
440 int res = 0;
441
442 vbytes.len = -1;
443 if (values == (PyObject *)self) {
444 /* Make a copy and call this function recursively */
445 int err;
446 values = PyByteArray_FromObject(values);
447 if (values == NULL)
448 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000449 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000450 Py_DECREF(values);
451 return err;
452 }
453 if (values == NULL) {
454 /* del b[lo:hi] */
455 bytes = NULL;
456 needed = 0;
457 }
458 else {
459 if (_getbuffer(values, &vbytes) < 0) {
460 PyErr_Format(PyExc_TypeError,
Georg Brandl3dbca812008-07-23 16:10:53 +0000461 "can't set bytearray slice from %.100s",
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000462 Py_TYPE(values)->tp_name);
463 return -1;
464 }
465 needed = vbytes.len;
466 bytes = vbytes.buf;
467 }
468
469 if (lo < 0)
470 lo = 0;
471 if (hi < lo)
472 hi = lo;
473 if (hi > Py_SIZE(self))
474 hi = Py_SIZE(self);
475
476 avail = hi - lo;
477 if (avail < 0)
478 lo = hi = avail = 0;
479
480 if (avail != needed) {
481 if (avail > needed) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000482 if (!_canresize(self)) {
483 res = -1;
484 goto finish;
485 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000486 /*
487 0 lo hi old_size
488 | |<----avail----->|<-----tomove------>|
489 | |<-needed->|<-----tomove------>|
490 0 lo new_hi new_size
491 */
492 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
493 Py_SIZE(self) - hi);
494 }
495 /* XXX(nnorwitz): need to verify this can't overflow! */
496 if (PyByteArray_Resize((PyObject *)self,
497 Py_SIZE(self) + needed - avail) < 0) {
498 res = -1;
499 goto finish;
500 }
501 if (avail < needed) {
502 /*
503 0 lo hi old_size
504 | |<-avail->|<-----tomove------>|
505 | |<----needed---->|<-----tomove------>|
506 0 lo new_hi new_size
507 */
508 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
509 Py_SIZE(self) - lo - needed);
510 }
511 }
512
513 if (needed > 0)
514 memcpy(self->ob_bytes + lo, bytes, needed);
515
516
517 finish:
518 if (vbytes.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000519 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000520 return res;
521}
522
523static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000524bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000525{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000526 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000527
528 if (i < 0)
529 i += Py_SIZE(self);
530
531 if (i < 0 || i >= Py_SIZE(self)) {
532 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
533 return -1;
534 }
535
536 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000537 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000538
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000539 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000540 return -1;
541
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000542 self->ob_bytes[i] = ival;
543 return 0;
544}
545
546static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000547bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000548{
549 Py_ssize_t start, stop, step, slicelen, needed;
550 char *bytes;
551
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000552 if (PyIndex_Check(index)) {
553 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000554
555 if (i == -1 && PyErr_Occurred())
556 return -1;
557
558 if (i < 0)
559 i += PyByteArray_GET_SIZE(self);
560
561 if (i < 0 || i >= Py_SIZE(self)) {
562 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
563 return -1;
564 }
565
566 if (values == NULL) {
567 /* Fall through to slice assignment */
568 start = i;
569 stop = i + 1;
570 step = 1;
571 slicelen = 1;
572 }
573 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000574 int ival;
575 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000576 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000577 self->ob_bytes[i] = (char)ival;
578 return 0;
579 }
580 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000581 else if (PySlice_Check(index)) {
582 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000583 PyByteArray_GET_SIZE(self),
584 &start, &stop, &step, &slicelen) < 0) {
585 return -1;
586 }
587 }
588 else {
589 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
590 return -1;
591 }
592
593 if (values == NULL) {
594 bytes = NULL;
595 needed = 0;
596 }
597 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
598 /* Make a copy an call this function recursively */
599 int err;
600 values = PyByteArray_FromObject(values);
601 if (values == NULL)
602 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000603 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000604 Py_DECREF(values);
605 return err;
606 }
607 else {
608 assert(PyByteArray_Check(values));
609 bytes = ((PyByteArrayObject *)values)->ob_bytes;
610 needed = Py_SIZE(values);
611 }
612 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
613 if ((step < 0 && start < stop) ||
614 (step > 0 && start > stop))
615 stop = start;
616 if (step == 1) {
617 if (slicelen != needed) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000618 if (!_canresize(self))
619 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000620 if (slicelen > needed) {
621 /*
622 0 start stop old_size
623 | |<---slicelen--->|<-----tomove------>|
624 | |<-needed->|<-----tomove------>|
625 0 lo new_hi new_size
626 */
627 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
628 Py_SIZE(self) - stop);
629 }
630 if (PyByteArray_Resize((PyObject *)self,
631 Py_SIZE(self) + needed - slicelen) < 0)
632 return -1;
633 if (slicelen < needed) {
634 /*
635 0 lo hi old_size
636 | |<-avail->|<-----tomove------>|
637 | |<----needed---->|<-----tomove------>|
638 0 lo new_hi new_size
639 */
640 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
641 Py_SIZE(self) - start - needed);
642 }
643 }
644
645 if (needed > 0)
646 memcpy(self->ob_bytes + start, bytes, needed);
647
648 return 0;
649 }
650 else {
651 if (needed == 0) {
652 /* Delete slice */
Mark Dickinsona53f2c92010-01-29 17:29:21 +0000653 size_t cur;
654 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000655
Antoine Pitrou5504e892008-12-06 21:27:53 +0000656 if (!_canresize(self))
657 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000658 if (step < 0) {
659 stop = start + 1;
660 start = stop + step * (slicelen - 1) - 1;
661 step = -step;
662 }
663 for (cur = start, i = 0;
664 i < slicelen; cur += step, i++) {
665 Py_ssize_t lim = step - 1;
666
667 if (cur + step >= PyByteArray_GET_SIZE(self))
668 lim = PyByteArray_GET_SIZE(self) - cur - 1;
669
670 memmove(self->ob_bytes + cur - i,
671 self->ob_bytes + cur + 1, lim);
672 }
673 /* Move the tail of the bytes, in one chunk */
674 cur = start + slicelen*step;
675 if (cur < PyByteArray_GET_SIZE(self)) {
676 memmove(self->ob_bytes + cur - slicelen,
677 self->ob_bytes + cur,
678 PyByteArray_GET_SIZE(self) - cur);
679 }
680 if (PyByteArray_Resize((PyObject *)self,
681 PyByteArray_GET_SIZE(self) - slicelen) < 0)
682 return -1;
683
684 return 0;
685 }
686 else {
687 /* Assign slice */
688 Py_ssize_t cur, i;
689
690 if (needed != slicelen) {
691 PyErr_Format(PyExc_ValueError,
692 "attempt to assign bytes of size %zd "
693 "to extended slice of size %zd",
694 needed, slicelen);
695 return -1;
696 }
697 for (cur = start, i = 0; i < slicelen; cur += step, i++)
698 self->ob_bytes[cur] = bytes[i];
699 return 0;
700 }
701 }
702}
703
704static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000705bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000706{
707 static char *kwlist[] = {"source", "encoding", "errors", 0};
708 PyObject *arg = NULL;
709 const char *encoding = NULL;
710 const char *errors = NULL;
711 Py_ssize_t count;
712 PyObject *it;
713 PyObject *(*iternext)(PyObject *);
714
715 if (Py_SIZE(self) != 0) {
716 /* Empty previous contents (yes, do this first of all!) */
717 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
718 return -1;
719 }
720
721 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000722 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000723 &arg, &encoding, &errors))
724 return -1;
725
726 /* Make a quick exit if no first argument */
727 if (arg == NULL) {
728 if (encoding != NULL || errors != NULL) {
729 PyErr_SetString(PyExc_TypeError,
730 "encoding or errors without sequence argument");
731 return -1;
732 }
733 return 0;
734 }
735
736 if (PyUnicode_Check(arg)) {
737 /* Encode via the codec registry */
738 PyObject *encoded, *new;
739 if (encoding == NULL) {
740 PyErr_SetString(PyExc_TypeError,
741 "string argument without an encoding");
742 return -1;
743 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000744 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000745 if (encoded == NULL)
746 return -1;
747 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000748 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000749 Py_DECREF(encoded);
750 if (new == NULL)
751 return -1;
752 Py_DECREF(new);
753 return 0;
754 }
755
756 /* If it's not unicode, there can't be encoding or errors */
757 if (encoding != NULL || errors != NULL) {
758 PyErr_SetString(PyExc_TypeError,
759 "encoding or errors without a string argument");
760 return -1;
761 }
762
763 /* Is it an int? */
764 count = PyNumber_AsSsize_t(arg, PyExc_ValueError);
765 if (count == -1 && PyErr_Occurred())
766 PyErr_Clear();
767 else {
768 if (count < 0) {
769 PyErr_SetString(PyExc_ValueError, "negative count");
770 return -1;
771 }
772 if (count > 0) {
773 if (PyByteArray_Resize((PyObject *)self, count))
774 return -1;
775 memset(self->ob_bytes, 0, count);
776 }
777 return 0;
778 }
779
780 /* Use the buffer API */
781 if (PyObject_CheckBuffer(arg)) {
782 Py_ssize_t size;
783 Py_buffer view;
784 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
785 return -1;
786 size = view.len;
787 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
788 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
789 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000790 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000791 return 0;
792 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000793 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000794 return -1;
795 }
796
797 /* XXX Optimize this if the arguments is a list, tuple */
798
799 /* Get the iterator */
800 it = PyObject_GetIter(arg);
801 if (it == NULL)
802 return -1;
803 iternext = *Py_TYPE(it)->tp_iternext;
804
805 /* Run the iterator to exhaustion */
806 for (;;) {
807 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000808 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000809
810 /* Get the next item */
811 item = iternext(it);
812 if (item == NULL) {
813 if (PyErr_Occurred()) {
814 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
815 goto error;
816 PyErr_Clear();
817 }
818 break;
819 }
820
821 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000822 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000823 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000824 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000825 goto error;
826
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000827 /* Append the byte */
828 if (Py_SIZE(self) < self->ob_alloc)
829 Py_SIZE(self)++;
830 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
831 goto error;
832 self->ob_bytes[Py_SIZE(self)-1] = value;
833 }
834
835 /* Clean up and return success */
836 Py_DECREF(it);
837 return 0;
838
839 error:
840 /* Error handling when it != NULL */
841 Py_DECREF(it);
842 return -1;
843}
844
845/* Mostly copied from string_repr, but without the
846 "smart quote" functionality. */
847static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000848bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000849{
850 static const char *hexdigits = "0123456789abcdef";
851 const char *quote_prefix = "bytearray(b";
852 const char *quote_postfix = ")";
853 Py_ssize_t length = Py_SIZE(self);
854 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
855 size_t newsize = 14 + 4 * length;
856 PyObject *v;
857 if (newsize > PY_SSIZE_T_MAX || newsize / 4 - 3 != length) {
858 PyErr_SetString(PyExc_OverflowError,
859 "bytearray object is too large to make repr");
860 return NULL;
861 }
862 v = PyUnicode_FromUnicode(NULL, newsize);
863 if (v == NULL) {
864 return NULL;
865 }
866 else {
867 register Py_ssize_t i;
868 register Py_UNICODE c;
869 register Py_UNICODE *p;
870 int quote;
871
872 /* Figure out which quote to use; single is preferred */
873 quote = '\'';
874 {
875 char *test, *start;
876 start = PyByteArray_AS_STRING(self);
877 for (test = start; test < start+length; ++test) {
878 if (*test == '"') {
879 quote = '\''; /* back to single */
880 goto decided;
881 }
882 else if (*test == '\'')
883 quote = '"';
884 }
885 decided:
886 ;
887 }
888
889 p = PyUnicode_AS_UNICODE(v);
890 while (*quote_prefix)
891 *p++ = *quote_prefix++;
892 *p++ = quote;
893
894 for (i = 0; i < length; i++) {
895 /* There's at least enough room for a hex escape
896 and a closing quote. */
897 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5);
898 c = self->ob_bytes[i];
899 if (c == '\'' || c == '\\')
900 *p++ = '\\', *p++ = c;
901 else if (c == '\t')
902 *p++ = '\\', *p++ = 't';
903 else if (c == '\n')
904 *p++ = '\\', *p++ = 'n';
905 else if (c == '\r')
906 *p++ = '\\', *p++ = 'r';
907 else if (c == 0)
908 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
909 else if (c < ' ' || c >= 0x7f) {
910 *p++ = '\\';
911 *p++ = 'x';
912 *p++ = hexdigits[(c & 0xf0) >> 4];
913 *p++ = hexdigits[c & 0xf];
914 }
915 else
916 *p++ = c;
917 }
918 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1);
919 *p++ = quote;
920 while (*quote_postfix) {
921 *p++ = *quote_postfix++;
922 }
923 *p = '\0';
924 if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
925 Py_DECREF(v);
926 return NULL;
927 }
928 return v;
929 }
930}
931
932static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000933bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000934{
935 if (Py_BytesWarningFlag) {
936 if (PyErr_WarnEx(PyExc_BytesWarning,
937 "str() on a bytearray instance", 1))
938 return NULL;
939 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000940 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000941}
942
943static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000944bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000945{
946 Py_ssize_t self_size, other_size;
947 Py_buffer self_bytes, other_bytes;
948 PyObject *res;
949 Py_ssize_t minsize;
950 int cmp;
951
952 /* Bytes can be compared to anything that supports the (binary)
953 buffer API. Except that a comparison with Unicode is always an
954 error, even if the comparison is for equality. */
955 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
956 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000957 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000958 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000959 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000960 return NULL;
961 }
962
963 Py_INCREF(Py_NotImplemented);
964 return Py_NotImplemented;
965 }
966
967 self_size = _getbuffer(self, &self_bytes);
968 if (self_size < 0) {
969 PyErr_Clear();
970 Py_INCREF(Py_NotImplemented);
971 return Py_NotImplemented;
972 }
973
974 other_size = _getbuffer(other, &other_bytes);
975 if (other_size < 0) {
976 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +0000977 PyBuffer_Release(&self_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000978 Py_INCREF(Py_NotImplemented);
979 return Py_NotImplemented;
980 }
981
982 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
983 /* Shortcut: if the lengths differ, the objects differ */
984 cmp = (op == Py_NE);
985 }
986 else {
987 minsize = self_size;
988 if (other_size < minsize)
989 minsize = other_size;
990
991 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
992 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
993
994 if (cmp == 0) {
995 if (self_size < other_size)
996 cmp = -1;
997 else if (self_size > other_size)
998 cmp = 1;
999 }
1000
1001 switch (op) {
1002 case Py_LT: cmp = cmp < 0; break;
1003 case Py_LE: cmp = cmp <= 0; break;
1004 case Py_EQ: cmp = cmp == 0; break;
1005 case Py_NE: cmp = cmp != 0; break;
1006 case Py_GT: cmp = cmp > 0; break;
1007 case Py_GE: cmp = cmp >= 0; break;
1008 }
1009 }
1010
1011 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001012 PyBuffer_Release(&self_bytes);
1013 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001014 Py_INCREF(res);
1015 return res;
1016}
1017
1018static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001019bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001020{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001021 if (self->ob_exports > 0) {
1022 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001023 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001024 PyErr_Print();
1025 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001026 if (self->ob_bytes != 0) {
1027 PyMem_Free(self->ob_bytes);
1028 }
1029 Py_TYPE(self)->tp_free((PyObject *)self);
1030}
1031
1032
1033/* -------------------------------------------------------------------- */
1034/* Methods */
1035
1036#define STRINGLIB_CHAR char
1037#define STRINGLIB_CMP memcmp
1038#define STRINGLIB_LEN PyByteArray_GET_SIZE
1039#define STRINGLIB_STR PyByteArray_AS_STRING
1040#define STRINGLIB_NEW PyByteArray_FromStringAndSize
1041#define STRINGLIB_EMPTY nullbytes
1042#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1043#define STRINGLIB_MUTABLE 1
Benjamin Petersona786b022008-08-25 21:05:21 +00001044#define FROM_BYTEARRAY 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001045
1046#include "stringlib/fastsearch.h"
1047#include "stringlib/count.h"
1048#include "stringlib/find.h"
1049#include "stringlib/partition.h"
1050#include "stringlib/ctype.h"
1051#include "stringlib/transmogrify.h"
1052
1053
1054/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1055were copied from the old char* style string object. */
1056
1057Py_LOCAL_INLINE(void)
1058_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len)
1059{
1060 if (*end > len)
1061 *end = len;
1062 else if (*end < 0)
1063 *end += len;
1064 if (*end < 0)
1065 *end = 0;
1066 if (*start < 0)
1067 *start += len;
1068 if (*start < 0)
1069 *start = 0;
1070}
1071
1072
1073Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001074bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001075{
1076 PyObject *subobj;
1077 Py_buffer subbuf;
1078 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1079 Py_ssize_t res;
1080
1081 if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
1082 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1083 return -2;
1084 if (_getbuffer(subobj, &subbuf) < 0)
1085 return -2;
1086 if (dir > 0)
1087 res = stringlib_find_slice(
1088 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1089 subbuf.buf, subbuf.len, start, end);
1090 else
1091 res = stringlib_rfind_slice(
1092 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1093 subbuf.buf, subbuf.len, start, end);
Martin v. Löwis423be952008-08-13 15:53:07 +00001094 PyBuffer_Release(&subbuf);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001095 return res;
1096}
1097
1098PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001099"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001100\n\
1101Return the lowest index in B where subsection sub is found,\n\
1102such that sub is contained within s[start,end]. Optional\n\
1103arguments start and end are interpreted as in slice notation.\n\
1104\n\
1105Return -1 on failure.");
1106
1107static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001108bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001109{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001110 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001111 if (result == -2)
1112 return NULL;
1113 return PyLong_FromSsize_t(result);
1114}
1115
1116PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001117"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001118\n\
1119Return the number of non-overlapping occurrences of subsection sub in\n\
1120bytes B[start:end]. Optional arguments start and end are interpreted\n\
1121as in slice notation.");
1122
1123static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001124bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001125{
1126 PyObject *sub_obj;
1127 const char *str = PyByteArray_AS_STRING(self);
1128 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1129 Py_buffer vsub;
1130 PyObject *count_obj;
1131
1132 if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1133 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1134 return NULL;
1135
1136 if (_getbuffer(sub_obj, &vsub) < 0)
1137 return NULL;
1138
1139 _adjust_indices(&start, &end, PyByteArray_GET_SIZE(self));
1140
1141 count_obj = PyLong_FromSsize_t(
1142 stringlib_count(str + start, end - start, vsub.buf, vsub.len)
1143 );
Martin v. Löwis423be952008-08-13 15:53:07 +00001144 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001145 return count_obj;
1146}
1147
1148
1149PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001150"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001151\n\
1152Like B.find() but raise ValueError when the subsection is not found.");
1153
1154static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001155bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001156{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001157 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001158 if (result == -2)
1159 return NULL;
1160 if (result == -1) {
1161 PyErr_SetString(PyExc_ValueError,
1162 "subsection not found");
1163 return NULL;
1164 }
1165 return PyLong_FromSsize_t(result);
1166}
1167
1168
1169PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001170"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001171\n\
1172Return the highest index in B where subsection sub is found,\n\
1173such that sub is contained within s[start,end]. Optional\n\
1174arguments start and end are interpreted as in slice notation.\n\
1175\n\
1176Return -1 on failure.");
1177
1178static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001179bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001180{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001181 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001182 if (result == -2)
1183 return NULL;
1184 return PyLong_FromSsize_t(result);
1185}
1186
1187
1188PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001189"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001190\n\
1191Like B.rfind() but raise ValueError when the subsection is not found.");
1192
1193static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001194bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001195{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001196 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001197 if (result == -2)
1198 return NULL;
1199 if (result == -1) {
1200 PyErr_SetString(PyExc_ValueError,
1201 "subsection not found");
1202 return NULL;
1203 }
1204 return PyLong_FromSsize_t(result);
1205}
1206
1207
1208static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001209bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001210{
1211 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1212 if (ival == -1 && PyErr_Occurred()) {
1213 Py_buffer varg;
1214 int pos;
1215 PyErr_Clear();
1216 if (_getbuffer(arg, &varg) < 0)
1217 return -1;
1218 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1219 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001220 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001221 return pos >= 0;
1222 }
1223 if (ival < 0 || ival >= 256) {
1224 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1225 return -1;
1226 }
1227
1228 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1229}
1230
1231
1232/* Matches the end (direction >= 0) or start (direction < 0) of self
1233 * against substr, using the start and end arguments. Returns
1234 * -1 on error, 0 if not found and 1 if found.
1235 */
1236Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001237_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001238 Py_ssize_t end, int direction)
1239{
1240 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1241 const char* str;
1242 Py_buffer vsubstr;
1243 int rv = 0;
1244
1245 str = PyByteArray_AS_STRING(self);
1246
1247 if (_getbuffer(substr, &vsubstr) < 0)
1248 return -1;
1249
1250 _adjust_indices(&start, &end, len);
1251
1252 if (direction < 0) {
1253 /* startswith */
1254 if (start+vsubstr.len > len) {
1255 goto done;
1256 }
1257 } else {
1258 /* endswith */
1259 if (end-start < vsubstr.len || start > len) {
1260 goto done;
1261 }
1262
1263 if (end-vsubstr.len > start)
1264 start = end - vsubstr.len;
1265 }
1266 if (end-start >= vsubstr.len)
1267 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1268
1269done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001270 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001271 return rv;
1272}
1273
1274
1275PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001276"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001277\n\
1278Return True if B starts with the specified prefix, False otherwise.\n\
1279With optional start, test B beginning at that position.\n\
1280With optional end, stop comparing B at that position.\n\
1281prefix can also be a tuple of strings to try.");
1282
1283static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001284bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001285{
1286 Py_ssize_t start = 0;
1287 Py_ssize_t end = PY_SSIZE_T_MAX;
1288 PyObject *subobj;
1289 int result;
1290
1291 if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
1292 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1293 return NULL;
1294 if (PyTuple_Check(subobj)) {
1295 Py_ssize_t i;
1296 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001297 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001298 PyTuple_GET_ITEM(subobj, i),
1299 start, end, -1);
1300 if (result == -1)
1301 return NULL;
1302 else if (result) {
1303 Py_RETURN_TRUE;
1304 }
1305 }
1306 Py_RETURN_FALSE;
1307 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001308 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001309 if (result == -1)
1310 return NULL;
1311 else
1312 return PyBool_FromLong(result);
1313}
1314
1315PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001316"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001317\n\
1318Return True if B ends with the specified suffix, False otherwise.\n\
1319With optional start, test B beginning at that position.\n\
1320With optional end, stop comparing B at that position.\n\
1321suffix can also be a tuple of strings to try.");
1322
1323static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001324bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001325{
1326 Py_ssize_t start = 0;
1327 Py_ssize_t end = PY_SSIZE_T_MAX;
1328 PyObject *subobj;
1329 int result;
1330
1331 if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
1332 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1333 return NULL;
1334 if (PyTuple_Check(subobj)) {
1335 Py_ssize_t i;
1336 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001337 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001338 PyTuple_GET_ITEM(subobj, i),
1339 start, end, +1);
1340 if (result == -1)
1341 return NULL;
1342 else if (result) {
1343 Py_RETURN_TRUE;
1344 }
1345 }
1346 Py_RETURN_FALSE;
1347 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001348 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001349 if (result == -1)
1350 return NULL;
1351 else
1352 return PyBool_FromLong(result);
1353}
1354
1355
1356PyDoc_STRVAR(translate__doc__,
1357"B.translate(table[, deletechars]) -> bytearray\n\
1358\n\
1359Return a copy of B, where all characters occurring in the\n\
1360optional argument deletechars are removed, and the remaining\n\
1361characters have been mapped through the given translation\n\
1362table, which must be a bytes object of length 256.");
1363
1364static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001365bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001366{
1367 register char *input, *output;
1368 register const char *table;
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001369 register Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001370 PyObject *input_obj = (PyObject*)self;
1371 const char *output_start;
1372 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001373 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001374 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001375 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001376 Py_buffer vtable, vdel;
1377
1378 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1379 &tableobj, &delobj))
1380 return NULL;
1381
Georg Brandlccc47b62008-12-28 11:44:14 +00001382 if (tableobj == Py_None) {
1383 table = NULL;
1384 tableobj = NULL;
1385 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001386 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001387 } else {
1388 if (vtable.len != 256) {
1389 PyErr_SetString(PyExc_ValueError,
1390 "translation table must be 256 characters long");
Georg Brandl069bcc32009-07-22 12:06:11 +00001391 PyBuffer_Release(&vtable);
1392 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001393 }
1394 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001395 }
1396
1397 if (delobj != NULL) {
1398 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl069bcc32009-07-22 12:06:11 +00001399 if (tableobj != NULL)
1400 PyBuffer_Release(&vtable);
1401 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001402 }
1403 }
1404 else {
1405 vdel.buf = NULL;
1406 vdel.len = 0;
1407 }
1408
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001409 inlen = PyByteArray_GET_SIZE(input_obj);
1410 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1411 if (result == NULL)
1412 goto done;
1413 output_start = output = PyByteArray_AsString(result);
1414 input = PyByteArray_AS_STRING(input_obj);
1415
Georg Brandlccc47b62008-12-28 11:44:14 +00001416 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001417 /* If no deletions are required, use faster code */
1418 for (i = inlen; --i >= 0; ) {
1419 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001420 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001421 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001422 goto done;
1423 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001424
1425 if (table == NULL) {
1426 for (i = 0; i < 256; i++)
1427 trans_table[i] = Py_CHARMASK(i);
1428 } else {
1429 for (i = 0; i < 256; i++)
1430 trans_table[i] = Py_CHARMASK(table[i]);
1431 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001432
1433 for (i = 0; i < vdel.len; i++)
1434 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1435
1436 for (i = inlen; --i >= 0; ) {
1437 c = Py_CHARMASK(*input++);
1438 if (trans_table[c] != -1)
1439 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1440 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001441 }
1442 /* Fix the size of the resulting string */
1443 if (inlen > 0)
1444 PyByteArray_Resize(result, output - output_start);
1445
1446done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001447 if (tableobj != NULL)
1448 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001449 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001450 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001451 return result;
1452}
1453
1454
Georg Brandlabc38772009-04-12 15:51:51 +00001455static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001456bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001457{
1458 return _Py_bytes_maketrans(args);
1459}
1460
1461
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001462#define FORWARD 1
1463#define REVERSE -1
1464
1465/* find and count characters and substrings */
1466
1467#define findchar(target, target_len, c) \
1468 ((char *)memchr((const void *)(target), c, target_len))
1469
1470/* Don't call if length < 2 */
1471#define Py_STRING_MATCH(target, offset, pattern, length) \
1472 (target[offset] == pattern[0] && \
1473 target[offset+length-1] == pattern[length-1] && \
1474 !memcmp(target+offset+1, pattern+1, length-2) )
1475
1476
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001477/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001478Py_LOCAL(PyByteArrayObject *)
1479return_self(PyByteArrayObject *self)
1480{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001481 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001482 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1483 PyByteArray_AS_STRING(self),
1484 PyByteArray_GET_SIZE(self));
1485}
1486
1487Py_LOCAL_INLINE(Py_ssize_t)
1488countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1489{
1490 Py_ssize_t count=0;
1491 const char *start=target;
1492 const char *end=target+target_len;
1493
1494 while ( (start=findchar(start, end-start, c)) != NULL ) {
1495 count++;
1496 if (count >= maxcount)
1497 break;
1498 start += 1;
1499 }
1500 return count;
1501}
1502
1503Py_LOCAL(Py_ssize_t)
1504findstring(const char *target, Py_ssize_t target_len,
1505 const char *pattern, Py_ssize_t pattern_len,
1506 Py_ssize_t start,
1507 Py_ssize_t end,
1508 int direction)
1509{
1510 if (start < 0) {
1511 start += target_len;
1512 if (start < 0)
1513 start = 0;
1514 }
1515 if (end > target_len) {
1516 end = target_len;
1517 } else if (end < 0) {
1518 end += target_len;
1519 if (end < 0)
1520 end = 0;
1521 }
1522
1523 /* zero-length substrings always match at the first attempt */
1524 if (pattern_len == 0)
1525 return (direction > 0) ? start : end;
1526
1527 end -= pattern_len;
1528
1529 if (direction < 0) {
1530 for (; end >= start; end--)
1531 if (Py_STRING_MATCH(target, end, pattern, pattern_len))
1532 return end;
1533 } else {
1534 for (; start <= end; start++)
1535 if (Py_STRING_MATCH(target, start, pattern, pattern_len))
1536 return start;
1537 }
1538 return -1;
1539}
1540
1541Py_LOCAL_INLINE(Py_ssize_t)
1542countstring(const char *target, Py_ssize_t target_len,
1543 const char *pattern, Py_ssize_t pattern_len,
1544 Py_ssize_t start,
1545 Py_ssize_t end,
1546 int direction, Py_ssize_t maxcount)
1547{
1548 Py_ssize_t count=0;
1549
1550 if (start < 0) {
1551 start += target_len;
1552 if (start < 0)
1553 start = 0;
1554 }
1555 if (end > target_len) {
1556 end = target_len;
1557 } else if (end < 0) {
1558 end += target_len;
1559 if (end < 0)
1560 end = 0;
1561 }
1562
1563 /* zero-length substrings match everywhere */
1564 if (pattern_len == 0 || maxcount == 0) {
1565 if (target_len+1 < maxcount)
1566 return target_len+1;
1567 return maxcount;
1568 }
1569
1570 end -= pattern_len;
1571 if (direction < 0) {
1572 for (; (end >= start); end--)
1573 if (Py_STRING_MATCH(target, end, pattern, pattern_len)) {
1574 count++;
1575 if (--maxcount <= 0) break;
1576 end -= pattern_len-1;
1577 }
1578 } else {
1579 for (; (start <= end); start++)
1580 if (Py_STRING_MATCH(target, start, pattern, pattern_len)) {
1581 count++;
1582 if (--maxcount <= 0)
1583 break;
1584 start += pattern_len-1;
1585 }
1586 }
1587 return count;
1588}
1589
1590
1591/* Algorithms for different cases of string replacement */
1592
1593/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1594Py_LOCAL(PyByteArrayObject *)
1595replace_interleave(PyByteArrayObject *self,
1596 const char *to_s, Py_ssize_t to_len,
1597 Py_ssize_t maxcount)
1598{
1599 char *self_s, *result_s;
1600 Py_ssize_t self_len, result_len;
1601 Py_ssize_t count, i, product;
1602 PyByteArrayObject *result;
1603
1604 self_len = PyByteArray_GET_SIZE(self);
1605
1606 /* 1 at the end plus 1 after every character */
1607 count = self_len+1;
1608 if (maxcount < count)
1609 count = maxcount;
1610
1611 /* Check for overflow */
1612 /* result_len = count * to_len + self_len; */
1613 product = count * to_len;
1614 if (product / to_len != count) {
1615 PyErr_SetString(PyExc_OverflowError,
1616 "replace string is too long");
1617 return NULL;
1618 }
1619 result_len = product + self_len;
1620 if (result_len < 0) {
1621 PyErr_SetString(PyExc_OverflowError,
1622 "replace string is too long");
1623 return NULL;
1624 }
1625
1626 if (! (result = (PyByteArrayObject *)
1627 PyByteArray_FromStringAndSize(NULL, result_len)) )
1628 return NULL;
1629
1630 self_s = PyByteArray_AS_STRING(self);
1631 result_s = PyByteArray_AS_STRING(result);
1632
1633 /* TODO: special case single character, which doesn't need memcpy */
1634
1635 /* Lay the first one down (guaranteed this will occur) */
1636 Py_MEMCPY(result_s, to_s, to_len);
1637 result_s += to_len;
1638 count -= 1;
1639
1640 for (i=0; i<count; i++) {
1641 *result_s++ = *self_s++;
1642 Py_MEMCPY(result_s, to_s, to_len);
1643 result_s += to_len;
1644 }
1645
1646 /* Copy the rest of the original string */
1647 Py_MEMCPY(result_s, self_s, self_len-i);
1648
1649 return result;
1650}
1651
1652/* Special case for deleting a single character */
1653/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1654Py_LOCAL(PyByteArrayObject *)
1655replace_delete_single_character(PyByteArrayObject *self,
1656 char from_c, Py_ssize_t maxcount)
1657{
1658 char *self_s, *result_s;
1659 char *start, *next, *end;
1660 Py_ssize_t self_len, result_len;
1661 Py_ssize_t count;
1662 PyByteArrayObject *result;
1663
1664 self_len = PyByteArray_GET_SIZE(self);
1665 self_s = PyByteArray_AS_STRING(self);
1666
1667 count = countchar(self_s, self_len, from_c, maxcount);
1668 if (count == 0) {
1669 return return_self(self);
1670 }
1671
1672 result_len = self_len - count; /* from_len == 1 */
1673 assert(result_len>=0);
1674
1675 if ( (result = (PyByteArrayObject *)
1676 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1677 return NULL;
1678 result_s = PyByteArray_AS_STRING(result);
1679
1680 start = self_s;
1681 end = self_s + self_len;
1682 while (count-- > 0) {
1683 next = findchar(start, end-start, from_c);
1684 if (next == NULL)
1685 break;
1686 Py_MEMCPY(result_s, start, next-start);
1687 result_s += (next-start);
1688 start = next+1;
1689 }
1690 Py_MEMCPY(result_s, start, end-start);
1691
1692 return result;
1693}
1694
1695/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1696
1697Py_LOCAL(PyByteArrayObject *)
1698replace_delete_substring(PyByteArrayObject *self,
1699 const char *from_s, Py_ssize_t from_len,
1700 Py_ssize_t maxcount)
1701{
1702 char *self_s, *result_s;
1703 char *start, *next, *end;
1704 Py_ssize_t self_len, result_len;
1705 Py_ssize_t count, offset;
1706 PyByteArrayObject *result;
1707
1708 self_len = PyByteArray_GET_SIZE(self);
1709 self_s = PyByteArray_AS_STRING(self);
1710
1711 count = countstring(self_s, self_len,
1712 from_s, from_len,
1713 0, self_len, 1,
1714 maxcount);
1715
1716 if (count == 0) {
1717 /* no matches */
1718 return return_self(self);
1719 }
1720
1721 result_len = self_len - (count * from_len);
1722 assert (result_len>=0);
1723
1724 if ( (result = (PyByteArrayObject *)
1725 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1726 return NULL;
1727
1728 result_s = PyByteArray_AS_STRING(result);
1729
1730 start = self_s;
1731 end = self_s + self_len;
1732 while (count-- > 0) {
1733 offset = findstring(start, end-start,
1734 from_s, from_len,
1735 0, end-start, FORWARD);
1736 if (offset == -1)
1737 break;
1738 next = start + offset;
1739
1740 Py_MEMCPY(result_s, start, next-start);
1741
1742 result_s += (next-start);
1743 start = next+from_len;
1744 }
1745 Py_MEMCPY(result_s, start, end-start);
1746 return result;
1747}
1748
1749/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1750Py_LOCAL(PyByteArrayObject *)
1751replace_single_character_in_place(PyByteArrayObject *self,
1752 char from_c, char to_c,
1753 Py_ssize_t maxcount)
1754{
1755 char *self_s, *result_s, *start, *end, *next;
1756 Py_ssize_t self_len;
1757 PyByteArrayObject *result;
1758
1759 /* The result string will be the same size */
1760 self_s = PyByteArray_AS_STRING(self);
1761 self_len = PyByteArray_GET_SIZE(self);
1762
1763 next = findchar(self_s, self_len, from_c);
1764
1765 if (next == NULL) {
1766 /* No matches; return the original bytes */
1767 return return_self(self);
1768 }
1769
1770 /* Need to make a new bytes */
1771 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1772 if (result == NULL)
1773 return NULL;
1774 result_s = PyByteArray_AS_STRING(result);
1775 Py_MEMCPY(result_s, self_s, self_len);
1776
1777 /* change everything in-place, starting with this one */
1778 start = result_s + (next-self_s);
1779 *start = to_c;
1780 start++;
1781 end = result_s + self_len;
1782
1783 while (--maxcount > 0) {
1784 next = findchar(start, end-start, from_c);
1785 if (next == NULL)
1786 break;
1787 *next = to_c;
1788 start = next+1;
1789 }
1790
1791 return result;
1792}
1793
1794/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1795Py_LOCAL(PyByteArrayObject *)
1796replace_substring_in_place(PyByteArrayObject *self,
1797 const char *from_s, Py_ssize_t from_len,
1798 const char *to_s, Py_ssize_t to_len,
1799 Py_ssize_t maxcount)
1800{
1801 char *result_s, *start, *end;
1802 char *self_s;
1803 Py_ssize_t self_len, offset;
1804 PyByteArrayObject *result;
1805
1806 /* The result bytes will be the same size */
1807
1808 self_s = PyByteArray_AS_STRING(self);
1809 self_len = PyByteArray_GET_SIZE(self);
1810
1811 offset = findstring(self_s, self_len,
1812 from_s, from_len,
1813 0, self_len, FORWARD);
1814 if (offset == -1) {
1815 /* No matches; return the original bytes */
1816 return return_self(self);
1817 }
1818
1819 /* Need to make a new bytes */
1820 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1821 if (result == NULL)
1822 return NULL;
1823 result_s = PyByteArray_AS_STRING(result);
1824 Py_MEMCPY(result_s, self_s, self_len);
1825
1826 /* change everything in-place, starting with this one */
1827 start = result_s + offset;
1828 Py_MEMCPY(start, to_s, from_len);
1829 start += from_len;
1830 end = result_s + self_len;
1831
1832 while ( --maxcount > 0) {
1833 offset = findstring(start, end-start,
1834 from_s, from_len,
1835 0, end-start, FORWARD);
1836 if (offset==-1)
1837 break;
1838 Py_MEMCPY(start+offset, to_s, from_len);
1839 start += offset+from_len;
1840 }
1841
1842 return result;
1843}
1844
1845/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1846Py_LOCAL(PyByteArrayObject *)
1847replace_single_character(PyByteArrayObject *self,
1848 char from_c,
1849 const char *to_s, Py_ssize_t to_len,
1850 Py_ssize_t maxcount)
1851{
1852 char *self_s, *result_s;
1853 char *start, *next, *end;
1854 Py_ssize_t self_len, result_len;
1855 Py_ssize_t count, product;
1856 PyByteArrayObject *result;
1857
1858 self_s = PyByteArray_AS_STRING(self);
1859 self_len = PyByteArray_GET_SIZE(self);
1860
1861 count = countchar(self_s, self_len, from_c, maxcount);
1862 if (count == 0) {
1863 /* no matches, return unchanged */
1864 return return_self(self);
1865 }
1866
1867 /* use the difference between current and new, hence the "-1" */
1868 /* result_len = self_len + count * (to_len-1) */
1869 product = count * (to_len-1);
1870 if (product / (to_len-1) != count) {
1871 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1872 return NULL;
1873 }
1874 result_len = self_len + product;
1875 if (result_len < 0) {
1876 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1877 return NULL;
1878 }
1879
1880 if ( (result = (PyByteArrayObject *)
1881 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1882 return NULL;
1883 result_s = PyByteArray_AS_STRING(result);
1884
1885 start = self_s;
1886 end = self_s + self_len;
1887 while (count-- > 0) {
1888 next = findchar(start, end-start, from_c);
1889 if (next == NULL)
1890 break;
1891
1892 if (next == start) {
1893 /* replace with the 'to' */
1894 Py_MEMCPY(result_s, to_s, to_len);
1895 result_s += to_len;
1896 start += 1;
1897 } else {
1898 /* copy the unchanged old then the 'to' */
1899 Py_MEMCPY(result_s, start, next-start);
1900 result_s += (next-start);
1901 Py_MEMCPY(result_s, to_s, to_len);
1902 result_s += to_len;
1903 start = next+1;
1904 }
1905 }
1906 /* Copy the remainder of the remaining bytes */
1907 Py_MEMCPY(result_s, start, end-start);
1908
1909 return result;
1910}
1911
1912/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1913Py_LOCAL(PyByteArrayObject *)
1914replace_substring(PyByteArrayObject *self,
1915 const char *from_s, Py_ssize_t from_len,
1916 const char *to_s, Py_ssize_t to_len,
1917 Py_ssize_t maxcount)
1918{
1919 char *self_s, *result_s;
1920 char *start, *next, *end;
1921 Py_ssize_t self_len, result_len;
1922 Py_ssize_t count, offset, product;
1923 PyByteArrayObject *result;
1924
1925 self_s = PyByteArray_AS_STRING(self);
1926 self_len = PyByteArray_GET_SIZE(self);
1927
1928 count = countstring(self_s, self_len,
1929 from_s, from_len,
1930 0, self_len, FORWARD, maxcount);
1931 if (count == 0) {
1932 /* no matches, return unchanged */
1933 return return_self(self);
1934 }
1935
1936 /* Check for overflow */
1937 /* result_len = self_len + count * (to_len-from_len) */
1938 product = count * (to_len-from_len);
1939 if (product / (to_len-from_len) != count) {
1940 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1941 return NULL;
1942 }
1943 result_len = self_len + product;
1944 if (result_len < 0) {
1945 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1946 return NULL;
1947 }
1948
1949 if ( (result = (PyByteArrayObject *)
1950 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1951 return NULL;
1952 result_s = PyByteArray_AS_STRING(result);
1953
1954 start = self_s;
1955 end = self_s + self_len;
1956 while (count-- > 0) {
1957 offset = findstring(start, end-start,
1958 from_s, from_len,
1959 0, end-start, FORWARD);
1960 if (offset == -1)
1961 break;
1962 next = start+offset;
1963 if (next == start) {
1964 /* replace with the 'to' */
1965 Py_MEMCPY(result_s, to_s, to_len);
1966 result_s += to_len;
1967 start += from_len;
1968 } else {
1969 /* copy the unchanged old then the 'to' */
1970 Py_MEMCPY(result_s, start, next-start);
1971 result_s += (next-start);
1972 Py_MEMCPY(result_s, to_s, to_len);
1973 result_s += to_len;
1974 start = next+from_len;
1975 }
1976 }
1977 /* Copy the remainder of the remaining bytes */
1978 Py_MEMCPY(result_s, start, end-start);
1979
1980 return result;
1981}
1982
1983
1984Py_LOCAL(PyByteArrayObject *)
1985replace(PyByteArrayObject *self,
1986 const char *from_s, Py_ssize_t from_len,
1987 const char *to_s, Py_ssize_t to_len,
1988 Py_ssize_t maxcount)
1989{
1990 if (maxcount < 0) {
1991 maxcount = PY_SSIZE_T_MAX;
1992 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1993 /* nothing to do; return the original bytes */
1994 return return_self(self);
1995 }
1996
1997 if (maxcount == 0 ||
1998 (from_len == 0 && to_len == 0)) {
1999 /* nothing to do; return the original bytes */
2000 return return_self(self);
2001 }
2002
2003 /* Handle zero-length special cases */
2004
2005 if (from_len == 0) {
2006 /* insert the 'to' bytes everywhere. */
2007 /* >>> "Python".replace("", ".") */
2008 /* '.P.y.t.h.o.n.' */
2009 return replace_interleave(self, to_s, to_len, maxcount);
2010 }
2011
2012 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2013 /* point for an empty self bytes to generate a non-empty bytes */
2014 /* Special case so the remaining code always gets a non-empty bytes */
2015 if (PyByteArray_GET_SIZE(self) == 0) {
2016 return return_self(self);
2017 }
2018
2019 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002020 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002021 if (from_len == 1) {
2022 return replace_delete_single_character(
2023 self, from_s[0], maxcount);
2024 } else {
2025 return replace_delete_substring(self, from_s, from_len, maxcount);
2026 }
2027 }
2028
2029 /* Handle special case where both bytes have the same length */
2030
2031 if (from_len == to_len) {
2032 if (from_len == 1) {
2033 return replace_single_character_in_place(
2034 self,
2035 from_s[0],
2036 to_s[0],
2037 maxcount);
2038 } else {
2039 return replace_substring_in_place(
2040 self, from_s, from_len, to_s, to_len, maxcount);
2041 }
2042 }
2043
2044 /* Otherwise use the more generic algorithms */
2045 if (from_len == 1) {
2046 return replace_single_character(self, from_s[0],
2047 to_s, to_len, maxcount);
2048 } else {
2049 /* len('from')>=2, len('to')>=1 */
2050 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2051 }
2052}
2053
2054
2055PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002056"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002057\n\
2058Return a copy of B with all occurrences of subsection\n\
2059old replaced by new. If the optional argument count is\n\
2060given, only the first count occurrences are replaced.");
2061
2062static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002063bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002064{
2065 Py_ssize_t count = -1;
2066 PyObject *from, *to, *res;
2067 Py_buffer vfrom, vto;
2068
2069 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2070 return NULL;
2071
2072 if (_getbuffer(from, &vfrom) < 0)
2073 return NULL;
2074 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +00002075 PyBuffer_Release(&vfrom);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002076 return NULL;
2077 }
2078
2079 res = (PyObject *)replace((PyByteArrayObject *) self,
2080 vfrom.buf, vfrom.len,
2081 vto.buf, vto.len, count);
2082
Martin v. Löwis423be952008-08-13 15:53:07 +00002083 PyBuffer_Release(&vfrom);
2084 PyBuffer_Release(&vto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002085 return res;
2086}
2087
2088
2089/* Overallocate the initial list to reduce the number of reallocs for small
2090 split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three
2091 resizes, to sizes 4, 8, then 16. Most observed string splits are for human
2092 text (roughly 11 words per line) and field delimited data (usually 1-10
2093 fields). For large strings the split algorithms are bandwidth limited
2094 so increasing the preallocation likely will not improve things.*/
2095
2096#define MAX_PREALLOC 12
2097
2098/* 5 splits gives 6 elements */
2099#define PREALLOC_SIZE(maxsplit) \
2100 (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
2101
2102#define SPLIT_APPEND(data, left, right) \
2103 str = PyByteArray_FromStringAndSize((data) + (left), \
2104 (right) - (left)); \
2105 if (str == NULL) \
2106 goto onError; \
2107 if (PyList_Append(list, str)) { \
2108 Py_DECREF(str); \
2109 goto onError; \
2110 } \
2111 else \
2112 Py_DECREF(str);
2113
2114#define SPLIT_ADD(data, left, right) { \
2115 str = PyByteArray_FromStringAndSize((data) + (left), \
2116 (right) - (left)); \
2117 if (str == NULL) \
2118 goto onError; \
2119 if (count < MAX_PREALLOC) { \
2120 PyList_SET_ITEM(list, count, str); \
2121 } else { \
2122 if (PyList_Append(list, str)) { \
2123 Py_DECREF(str); \
2124 goto onError; \
2125 } \
2126 else \
2127 Py_DECREF(str); \
2128 } \
2129 count++; }
2130
2131/* Always force the list to the expected size. */
2132#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
2133
2134
2135Py_LOCAL_INLINE(PyObject *)
2136split_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
2137{
2138 register Py_ssize_t i, j, count = 0;
2139 PyObject *str;
2140 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2141
2142 if (list == NULL)
2143 return NULL;
2144
2145 i = j = 0;
2146 while ((j < len) && (maxcount-- > 0)) {
2147 for(; j < len; j++) {
2148 /* I found that using memchr makes no difference */
2149 if (s[j] == ch) {
2150 SPLIT_ADD(s, i, j);
2151 i = j = j + 1;
2152 break;
2153 }
2154 }
2155 }
2156 if (i <= len) {
2157 SPLIT_ADD(s, i, len);
2158 }
2159 FIX_PREALLOC_SIZE(list);
2160 return list;
2161
2162 onError:
2163 Py_DECREF(list);
2164 return NULL;
2165}
2166
2167
2168Py_LOCAL_INLINE(PyObject *)
2169split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
2170{
2171 register Py_ssize_t i, j, count = 0;
2172 PyObject *str;
2173 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2174
2175 if (list == NULL)
2176 return NULL;
2177
2178 for (i = j = 0; i < len; ) {
2179 /* find a token */
Eric Smith6dc46f52009-04-27 20:39:49 +00002180 while (i < len && Py_ISSPACE(s[i]))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002181 i++;
2182 j = i;
Eric Smith6dc46f52009-04-27 20:39:49 +00002183 while (i < len && !Py_ISSPACE(s[i]))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002184 i++;
2185 if (j < i) {
2186 if (maxcount-- <= 0)
2187 break;
2188 SPLIT_ADD(s, j, i);
Eric Smith6dc46f52009-04-27 20:39:49 +00002189 while (i < len && Py_ISSPACE(s[i]))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002190 i++;
2191 j = i;
2192 }
2193 }
2194 if (j < len) {
2195 SPLIT_ADD(s, j, len);
2196 }
2197 FIX_PREALLOC_SIZE(list);
2198 return list;
2199
2200 onError:
2201 Py_DECREF(list);
2202 return NULL;
2203}
2204
2205PyDoc_STRVAR(split__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002206"B.split([sep[, maxsplit]]) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002207\n\
2208Return a list of the sections in B, using sep as the delimiter.\n\
2209If sep is not given, B is split on ASCII whitespace characters\n\
2210(space, tab, return, newline, formfeed, vertical tab).\n\
2211If maxsplit is given, at most maxsplit splits are done.");
2212
2213static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002214bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002215{
2216 Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
2217 Py_ssize_t maxsplit = -1, count = 0;
2218 const char *s = PyByteArray_AS_STRING(self), *sub;
2219 PyObject *list, *str, *subobj = Py_None;
2220 Py_buffer vsub;
2221#ifdef USE_FAST
2222 Py_ssize_t pos;
2223#endif
2224
2225 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2226 return NULL;
2227 if (maxsplit < 0)
2228 maxsplit = PY_SSIZE_T_MAX;
2229
2230 if (subobj == Py_None)
2231 return split_whitespace(s, len, maxsplit);
2232
2233 if (_getbuffer(subobj, &vsub) < 0)
2234 return NULL;
2235 sub = vsub.buf;
2236 n = vsub.len;
2237
2238 if (n == 0) {
2239 PyErr_SetString(PyExc_ValueError, "empty separator");
Martin v. Löwis423be952008-08-13 15:53:07 +00002240 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002241 return NULL;
2242 }
Benjamin Petersonc4fe6f32008-08-19 18:57:56 +00002243 if (n == 1) {
2244 list = split_char(s, len, sub[0], maxsplit);
2245 PyBuffer_Release(&vsub);
2246 return list;
2247 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002248
2249 list = PyList_New(PREALLOC_SIZE(maxsplit));
2250 if (list == NULL) {
Martin v. Löwis423be952008-08-13 15:53:07 +00002251 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002252 return NULL;
2253 }
2254
2255#ifdef USE_FAST
2256 i = j = 0;
2257 while (maxsplit-- > 0) {
2258 pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH);
2259 if (pos < 0)
2260 break;
2261 j = i+pos;
2262 SPLIT_ADD(s, i, j);
2263 i = j + n;
2264 }
2265#else
2266 i = j = 0;
2267 while ((j+n <= len) && (maxsplit-- > 0)) {
2268 for (; j+n <= len; j++) {
2269 if (Py_STRING_MATCH(s, j, sub, n)) {
2270 SPLIT_ADD(s, i, j);
2271 i = j = j + n;
2272 break;
2273 }
2274 }
2275 }
2276#endif
2277 SPLIT_ADD(s, i, len);
2278 FIX_PREALLOC_SIZE(list);
Martin v. Löwis423be952008-08-13 15:53:07 +00002279 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002280 return list;
2281
2282 onError:
2283 Py_DECREF(list);
Martin v. Löwis423be952008-08-13 15:53:07 +00002284 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002285 return NULL;
2286}
2287
2288/* stringlib's partition shares nullbytes in some cases.
2289 undo this, we don't want the nullbytes to be shared. */
2290static PyObject *
2291make_nullbytes_unique(PyObject *result)
2292{
2293 if (result != NULL) {
2294 int i;
2295 assert(PyTuple_Check(result));
2296 assert(PyTuple_GET_SIZE(result) == 3);
2297 for (i = 0; i < 3; i++) {
2298 if (PyTuple_GET_ITEM(result, i) == (PyObject *)nullbytes) {
2299 PyObject *new = PyByteArray_FromStringAndSize(NULL, 0);
2300 if (new == NULL) {
2301 Py_DECREF(result);
2302 result = NULL;
2303 break;
2304 }
2305 Py_DECREF(nullbytes);
2306 PyTuple_SET_ITEM(result, i, new);
2307 }
2308 }
2309 }
2310 return result;
2311}
2312
2313PyDoc_STRVAR(partition__doc__,
2314"B.partition(sep) -> (head, sep, tail)\n\
2315\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002316Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002317the separator itself, and the part after it. If the separator is not\n\
2318found, returns B and two empty bytearray objects.");
2319
2320static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002321bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002322{
2323 PyObject *bytesep, *result;
2324
2325 bytesep = PyByteArray_FromObject(sep_obj);
2326 if (! bytesep)
2327 return NULL;
2328
2329 result = stringlib_partition(
2330 (PyObject*) self,
2331 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2332 bytesep,
2333 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2334 );
2335
2336 Py_DECREF(bytesep);
2337 return make_nullbytes_unique(result);
2338}
2339
2340PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti4c81fbb2010-01-25 12:02:24 +00002341"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002342\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002343Search for the separator sep in B, starting at the end of B,\n\
2344and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002345part after it. If the separator is not found, returns two empty\n\
2346bytearray objects and B.");
2347
2348static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002349bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002350{
2351 PyObject *bytesep, *result;
2352
2353 bytesep = PyByteArray_FromObject(sep_obj);
2354 if (! bytesep)
2355 return NULL;
2356
2357 result = stringlib_rpartition(
2358 (PyObject*) self,
2359 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2360 bytesep,
2361 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2362 );
2363
2364 Py_DECREF(bytesep);
2365 return make_nullbytes_unique(result);
2366}
2367
2368Py_LOCAL_INLINE(PyObject *)
2369rsplit_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
2370{
2371 register Py_ssize_t i, j, count=0;
2372 PyObject *str;
2373 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2374
2375 if (list == NULL)
2376 return NULL;
2377
2378 i = j = len - 1;
2379 while ((i >= 0) && (maxcount-- > 0)) {
2380 for (; i >= 0; i--) {
2381 if (s[i] == ch) {
2382 SPLIT_ADD(s, i + 1, j + 1);
2383 j = i = i - 1;
2384 break;
2385 }
2386 }
2387 }
2388 if (j >= -1) {
2389 SPLIT_ADD(s, 0, j + 1);
2390 }
2391 FIX_PREALLOC_SIZE(list);
2392 if (PyList_Reverse(list) < 0)
2393 goto onError;
2394
2395 return list;
2396
2397 onError:
2398 Py_DECREF(list);
2399 return NULL;
2400}
2401
2402Py_LOCAL_INLINE(PyObject *)
2403rsplit_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
2404{
2405 register Py_ssize_t i, j, count = 0;
2406 PyObject *str;
2407 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2408
2409 if (list == NULL)
2410 return NULL;
2411
2412 for (i = j = len - 1; i >= 0; ) {
2413 /* find a token */
Eric Smith6dc46f52009-04-27 20:39:49 +00002414 while (i >= 0 && Py_ISSPACE(s[i]))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002415 i--;
2416 j = i;
Eric Smith6dc46f52009-04-27 20:39:49 +00002417 while (i >= 0 && !Py_ISSPACE(s[i]))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002418 i--;
2419 if (j > i) {
2420 if (maxcount-- <= 0)
2421 break;
2422 SPLIT_ADD(s, i + 1, j + 1);
Eric Smith6dc46f52009-04-27 20:39:49 +00002423 while (i >= 0 && Py_ISSPACE(s[i]))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002424 i--;
2425 j = i;
2426 }
2427 }
2428 if (j >= 0) {
2429 SPLIT_ADD(s, 0, j + 1);
2430 }
2431 FIX_PREALLOC_SIZE(list);
2432 if (PyList_Reverse(list) < 0)
2433 goto onError;
2434
2435 return list;
2436
2437 onError:
2438 Py_DECREF(list);
2439 return NULL;
2440}
2441
2442PyDoc_STRVAR(rsplit__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002443"B.rsplit(sep[, maxsplit]) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002444\n\
2445Return a list of the sections in B, using sep as the delimiter,\n\
2446starting at the end of B and working to the front.\n\
2447If sep is not given, B is split on ASCII whitespace characters\n\
2448(space, tab, return, newline, formfeed, vertical tab).\n\
2449If maxsplit is given, at most maxsplit splits are done.");
2450
2451static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002452bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002453{
2454 Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
2455 Py_ssize_t maxsplit = -1, count = 0;
2456 const char *s = PyByteArray_AS_STRING(self), *sub;
2457 PyObject *list, *str, *subobj = Py_None;
2458 Py_buffer vsub;
2459
2460 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2461 return NULL;
2462 if (maxsplit < 0)
2463 maxsplit = PY_SSIZE_T_MAX;
2464
2465 if (subobj == Py_None)
2466 return rsplit_whitespace(s, len, maxsplit);
2467
2468 if (_getbuffer(subobj, &vsub) < 0)
2469 return NULL;
2470 sub = vsub.buf;
2471 n = vsub.len;
2472
2473 if (n == 0) {
2474 PyErr_SetString(PyExc_ValueError, "empty separator");
Martin v. Löwis423be952008-08-13 15:53:07 +00002475 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002476 return NULL;
2477 }
Benjamin Petersonc4fe6f32008-08-19 18:57:56 +00002478 else if (n == 1) {
2479 list = rsplit_char(s, len, sub[0], maxsplit);
2480 PyBuffer_Release(&vsub);
2481 return list;
2482 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002483
2484 list = PyList_New(PREALLOC_SIZE(maxsplit));
2485 if (list == NULL) {
Martin v. Löwis423be952008-08-13 15:53:07 +00002486 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002487 return NULL;
2488 }
2489
2490 j = len;
2491 i = j - n;
2492
2493 while ( (i >= 0) && (maxsplit-- > 0) ) {
2494 for (; i>=0; i--) {
2495 if (Py_STRING_MATCH(s, i, sub, n)) {
2496 SPLIT_ADD(s, i + n, j);
2497 j = i;
2498 i -= n;
2499 break;
2500 }
2501 }
2502 }
2503 SPLIT_ADD(s, 0, j);
2504 FIX_PREALLOC_SIZE(list);
2505 if (PyList_Reverse(list) < 0)
2506 goto onError;
Martin v. Löwis423be952008-08-13 15:53:07 +00002507 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002508 return list;
2509
2510onError:
2511 Py_DECREF(list);
Martin v. Löwis423be952008-08-13 15:53:07 +00002512 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002513 return NULL;
2514}
2515
2516PyDoc_STRVAR(reverse__doc__,
2517"B.reverse() -> None\n\
2518\n\
2519Reverse the order of the values in B in place.");
2520static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002521bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002522{
2523 char swap, *head, *tail;
2524 Py_ssize_t i, j, n = Py_SIZE(self);
2525
2526 j = n / 2;
2527 head = self->ob_bytes;
2528 tail = head + n - 1;
2529 for (i = 0; i < j; i++) {
2530 swap = *head;
2531 *head++ = *tail;
2532 *tail-- = swap;
2533 }
2534
2535 Py_RETURN_NONE;
2536}
2537
2538PyDoc_STRVAR(insert__doc__,
2539"B.insert(index, int) -> None\n\
2540\n\
2541Insert a single item into the bytearray before the given index.");
2542static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002543bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002544{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002545 PyObject *value;
2546 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002547 Py_ssize_t where, n = Py_SIZE(self);
2548
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002549 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002550 return NULL;
2551
2552 if (n == PY_SSIZE_T_MAX) {
2553 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson099d7a02009-09-06 10:35:38 +00002554 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002555 return NULL;
2556 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002557 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002558 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002559 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2560 return NULL;
2561
2562 if (where < 0) {
2563 where += n;
2564 if (where < 0)
2565 where = 0;
2566 }
2567 if (where > n)
2568 where = n;
2569 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002570 self->ob_bytes[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002571
2572 Py_RETURN_NONE;
2573}
2574
2575PyDoc_STRVAR(append__doc__,
2576"B.append(int) -> None\n\
2577\n\
2578Append a single item to the end of B.");
2579static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002580bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002581{
2582 int value;
2583 Py_ssize_t n = Py_SIZE(self);
2584
2585 if (! _getbytevalue(arg, &value))
2586 return NULL;
2587 if (n == PY_SSIZE_T_MAX) {
2588 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson099d7a02009-09-06 10:35:38 +00002589 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002590 return NULL;
2591 }
2592 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2593 return NULL;
2594
2595 self->ob_bytes[n] = value;
2596
2597 Py_RETURN_NONE;
2598}
2599
2600PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002601"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002602\n\
2603Append all the elements from the iterator or sequence to the\n\
2604end of B.");
2605static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002606bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002607{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002608 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002609 Py_ssize_t buf_size = 0, len = 0;
2610 int value;
2611 char *buf;
2612
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002613 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002614 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002615 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002616 return NULL;
2617
2618 Py_RETURN_NONE;
2619 }
2620
2621 it = PyObject_GetIter(arg);
2622 if (it == NULL)
2623 return NULL;
2624
2625 /* Try to determine the length of the argument. 32 is abitrary. */
2626 buf_size = _PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002627 if (buf_size == -1) {
2628 Py_DECREF(it);
2629 return NULL;
2630 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002631
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002632 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2633 if (bytearray_obj == NULL)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002634 return NULL;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002635 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002636
2637 while ((item = PyIter_Next(it)) != NULL) {
2638 if (! _getbytevalue(item, &value)) {
2639 Py_DECREF(item);
2640 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002641 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002642 return NULL;
2643 }
2644 buf[len++] = value;
2645 Py_DECREF(item);
2646
2647 if (len >= buf_size) {
2648 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002649 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002650 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002651 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002652 return NULL;
2653 }
2654 /* Recompute the `buf' pointer, since the resizing operation may
2655 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002656 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002657 }
2658 }
2659 Py_DECREF(it);
2660
2661 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002662 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2663 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002664 return NULL;
2665 }
2666
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002667 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002668 return NULL;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002669 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002670
2671 Py_RETURN_NONE;
2672}
2673
2674PyDoc_STRVAR(pop__doc__,
2675"B.pop([index]) -> int\n\
2676\n\
2677Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002678argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002679static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002680bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002681{
2682 int value;
2683 Py_ssize_t where = -1, n = Py_SIZE(self);
2684
2685 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2686 return NULL;
2687
2688 if (n == 0) {
2689 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson099d7a02009-09-06 10:35:38 +00002690 "cannot pop an empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002691 return NULL;
2692 }
2693 if (where < 0)
2694 where += Py_SIZE(self);
2695 if (where < 0 || where >= Py_SIZE(self)) {
2696 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2697 return NULL;
2698 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002699 if (!_canresize(self))
2700 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002701
2702 value = self->ob_bytes[where];
2703 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2704 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2705 return NULL;
2706
Mark Dickinson424d75a2009-09-06 10:20:23 +00002707 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002708}
2709
2710PyDoc_STRVAR(remove__doc__,
2711"B.remove(int) -> None\n\
2712\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002713Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002714static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002715bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002716{
2717 int value;
2718 Py_ssize_t where, n = Py_SIZE(self);
2719
2720 if (! _getbytevalue(arg, &value))
2721 return NULL;
2722
2723 for (where = 0; where < n; where++) {
2724 if (self->ob_bytes[where] == value)
2725 break;
2726 }
2727 if (where == n) {
Mark Dickinson099d7a02009-09-06 10:35:38 +00002728 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002729 return NULL;
2730 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002731 if (!_canresize(self))
2732 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002733
2734 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2735 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2736 return NULL;
2737
2738 Py_RETURN_NONE;
2739}
2740
2741/* XXX These two helpers could be optimized if argsize == 1 */
2742
2743static Py_ssize_t
2744lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2745 void *argptr, Py_ssize_t argsize)
2746{
2747 Py_ssize_t i = 0;
2748 while (i < mysize && memchr(argptr, myptr[i], argsize))
2749 i++;
2750 return i;
2751}
2752
2753static Py_ssize_t
2754rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2755 void *argptr, Py_ssize_t argsize)
2756{
2757 Py_ssize_t i = mysize - 1;
2758 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2759 i--;
2760 return i + 1;
2761}
2762
2763PyDoc_STRVAR(strip__doc__,
2764"B.strip([bytes]) -> bytearray\n\
2765\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002766Strip leading and trailing bytes contained in the argument\n\
2767and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002768If the argument is omitted, strip ASCII whitespace.");
2769static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002770bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002771{
2772 Py_ssize_t left, right, mysize, argsize;
2773 void *myptr, *argptr;
2774 PyObject *arg = Py_None;
2775 Py_buffer varg;
2776 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2777 return NULL;
2778 if (arg == Py_None) {
2779 argptr = "\t\n\r\f\v ";
2780 argsize = 6;
2781 }
2782 else {
2783 if (_getbuffer(arg, &varg) < 0)
2784 return NULL;
2785 argptr = varg.buf;
2786 argsize = varg.len;
2787 }
2788 myptr = self->ob_bytes;
2789 mysize = Py_SIZE(self);
2790 left = lstrip_helper(myptr, mysize, argptr, argsize);
2791 if (left == mysize)
2792 right = left;
2793 else
2794 right = rstrip_helper(myptr, mysize, argptr, argsize);
2795 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002796 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002797 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2798}
2799
2800PyDoc_STRVAR(lstrip__doc__,
2801"B.lstrip([bytes]) -> bytearray\n\
2802\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002803Strip leading bytes contained in the argument\n\
2804and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002805If the argument is omitted, strip leading ASCII whitespace.");
2806static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002807bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002808{
2809 Py_ssize_t left, right, mysize, argsize;
2810 void *myptr, *argptr;
2811 PyObject *arg = Py_None;
2812 Py_buffer varg;
2813 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2814 return NULL;
2815 if (arg == Py_None) {
2816 argptr = "\t\n\r\f\v ";
2817 argsize = 6;
2818 }
2819 else {
2820 if (_getbuffer(arg, &varg) < 0)
2821 return NULL;
2822 argptr = varg.buf;
2823 argsize = varg.len;
2824 }
2825 myptr = self->ob_bytes;
2826 mysize = Py_SIZE(self);
2827 left = lstrip_helper(myptr, mysize, argptr, argsize);
2828 right = mysize;
2829 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002830 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002831 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2832}
2833
2834PyDoc_STRVAR(rstrip__doc__,
2835"B.rstrip([bytes]) -> bytearray\n\
2836\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002837Strip trailing bytes contained in the argument\n\
2838and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002839If the argument is omitted, strip trailing ASCII whitespace.");
2840static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002841bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002842{
2843 Py_ssize_t left, right, mysize, argsize;
2844 void *myptr, *argptr;
2845 PyObject *arg = Py_None;
2846 Py_buffer varg;
2847 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2848 return NULL;
2849 if (arg == Py_None) {
2850 argptr = "\t\n\r\f\v ";
2851 argsize = 6;
2852 }
2853 else {
2854 if (_getbuffer(arg, &varg) < 0)
2855 return NULL;
2856 argptr = varg.buf;
2857 argsize = varg.len;
2858 }
2859 myptr = self->ob_bytes;
2860 mysize = Py_SIZE(self);
2861 left = 0;
2862 right = rstrip_helper(myptr, mysize, argptr, argsize);
2863 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002864 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002865 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2866}
2867
2868PyDoc_STRVAR(decode_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002869"B.decode([encoding[, errors]]) -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002870\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002871Decode B using the codec registered for encoding. encoding defaults\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002872to the default encoding. errors may be given to set a different error\n\
2873handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2874a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2875as well as any other name registered with codecs.register_error that is\n\
2876able to handle UnicodeDecodeErrors.");
2877
2878static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002879bytearray_decode(PyObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002880{
2881 const char *encoding = NULL;
2882 const char *errors = NULL;
2883
2884 if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
2885 return NULL;
2886 if (encoding == NULL)
2887 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002888 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002889}
2890
2891PyDoc_STRVAR(alloc_doc,
2892"B.__alloc__() -> int\n\
2893\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002894Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002895
2896static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002897bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002898{
2899 return PyLong_FromSsize_t(self->ob_alloc);
2900}
2901
2902PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002903"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002904\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002905Concatenate any number of bytes/bytearray objects, with B\n\
2906in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002907
2908static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002909bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002910{
2911 PyObject *seq;
2912 Py_ssize_t mysize = Py_SIZE(self);
2913 Py_ssize_t i;
2914 Py_ssize_t n;
2915 PyObject **items;
2916 Py_ssize_t totalsize = 0;
2917 PyObject *result;
2918 char *dest;
2919
2920 seq = PySequence_Fast(it, "can only join an iterable");
2921 if (seq == NULL)
2922 return NULL;
2923 n = PySequence_Fast_GET_SIZE(seq);
2924 items = PySequence_Fast_ITEMS(seq);
2925
2926 /* Compute the total size, and check that they are all bytes */
2927 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2928 for (i = 0; i < n; i++) {
2929 PyObject *obj = items[i];
2930 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2931 PyErr_Format(PyExc_TypeError,
2932 "can only join an iterable of bytes "
2933 "(item %ld has type '%.100s')",
2934 /* XXX %ld isn't right on Win64 */
2935 (long)i, Py_TYPE(obj)->tp_name);
2936 goto error;
2937 }
2938 if (i > 0)
2939 totalsize += mysize;
2940 totalsize += Py_SIZE(obj);
2941 if (totalsize < 0) {
2942 PyErr_NoMemory();
2943 goto error;
2944 }
2945 }
2946
2947 /* Allocate the result, and copy the bytes */
2948 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2949 if (result == NULL)
2950 goto error;
2951 dest = PyByteArray_AS_STRING(result);
2952 for (i = 0; i < n; i++) {
2953 PyObject *obj = items[i];
2954 Py_ssize_t size = Py_SIZE(obj);
2955 char *buf;
2956 if (PyByteArray_Check(obj))
2957 buf = PyByteArray_AS_STRING(obj);
2958 else
2959 buf = PyBytes_AS_STRING(obj);
2960 if (i) {
2961 memcpy(dest, self->ob_bytes, mysize);
2962 dest += mysize;
2963 }
2964 memcpy(dest, buf, size);
2965 dest += size;
2966 }
2967
2968 /* Done */
2969 Py_DECREF(seq);
2970 return result;
2971
2972 /* Error handling */
2973 error:
2974 Py_DECREF(seq);
2975 return NULL;
2976}
2977
2978PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002979"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002980\n\
2981Create a bytearray object from a string of hexadecimal numbers.\n\
2982Spaces between two numbers are accepted.\n\
2983Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2984
2985static int
2986hex_digit_to_int(Py_UNICODE c)
2987{
2988 if (c >= 128)
2989 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002990 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002991 return c - '0';
2992 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002993 if (Py_ISUPPER(c))
2994 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002995 if (c >= 'a' && c <= 'f')
2996 return c - 'a' + 10;
2997 }
2998 return -1;
2999}
3000
3001static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003002bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003003{
3004 PyObject *newbytes, *hexobj;
3005 char *buf;
3006 Py_UNICODE *hex;
3007 Py_ssize_t hexlen, byteslen, i, j;
3008 int top, bot;
3009
3010 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
3011 return NULL;
3012 assert(PyUnicode_Check(hexobj));
3013 hexlen = PyUnicode_GET_SIZE(hexobj);
3014 hex = PyUnicode_AS_UNICODE(hexobj);
3015 byteslen = hexlen/2; /* This overestimates if there are spaces */
3016 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
3017 if (!newbytes)
3018 return NULL;
3019 buf = PyByteArray_AS_STRING(newbytes);
3020 for (i = j = 0; i < hexlen; i += 2) {
3021 /* skip over spaces in the input */
3022 while (hex[i] == ' ')
3023 i++;
3024 if (i >= hexlen)
3025 break;
3026 top = hex_digit_to_int(hex[i]);
3027 bot = hex_digit_to_int(hex[i+1]);
3028 if (top == -1 || bot == -1) {
3029 PyErr_Format(PyExc_ValueError,
3030 "non-hexadecimal number found in "
3031 "fromhex() arg at position %zd", i);
3032 goto error;
3033 }
3034 buf[j++] = (top << 4) + bot;
3035 }
3036 if (PyByteArray_Resize(newbytes, j) < 0)
3037 goto error;
3038 return newbytes;
3039
3040 error:
3041 Py_DECREF(newbytes);
3042 return NULL;
3043}
3044
3045PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
3046
3047static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003048bytearray_reduce(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003049{
3050 PyObject *latin1, *dict;
3051 if (self->ob_bytes)
3052 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
3053 Py_SIZE(self), NULL);
3054 else
3055 latin1 = PyUnicode_FromString("");
3056
3057 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
3058 if (dict == NULL) {
3059 PyErr_Clear();
3060 dict = Py_None;
3061 Py_INCREF(dict);
3062 }
3063
3064 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
3065}
3066
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003067PyDoc_STRVAR(sizeof_doc,
3068"B.__sizeof__() -> int\n\
3069 \n\
3070Returns the size of B in memory, in bytes");
3071static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003072bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003073{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00003074 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003075
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00003076 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
3077 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003078}
3079
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003080static PySequenceMethods bytearray_as_sequence = {
3081 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003082 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003083 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
3084 (ssizeargfunc)bytearray_getitem, /* sq_item */
3085 0, /* sq_slice */
3086 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
3087 0, /* sq_ass_slice */
3088 (objobjproc)bytearray_contains, /* sq_contains */
3089 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
3090 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003091};
3092
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003093static PyMappingMethods bytearray_as_mapping = {
3094 (lenfunc)bytearray_length,
3095 (binaryfunc)bytearray_subscript,
3096 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003097};
3098
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003099static PyBufferProcs bytearray_as_buffer = {
3100 (getbufferproc)bytearray_getbuffer,
3101 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003102};
3103
3104static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003105bytearray_methods[] = {
3106 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
3107 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
3108 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
3109 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003110 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
3111 _Py_capitalize__doc__},
3112 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003113 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
3114 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS, decode_doc},
3115 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003116 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
3117 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003118 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
3119 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
3120 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003121 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003122 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
3123 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003124 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
3125 _Py_isalnum__doc__},
3126 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
3127 _Py_isalpha__doc__},
3128 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
3129 _Py_isdigit__doc__},
3130 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
3131 _Py_islower__doc__},
3132 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
3133 _Py_isspace__doc__},
3134 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
3135 _Py_istitle__doc__},
3136 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
3137 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003138 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003139 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
3140 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003141 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
3142 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00003143 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003144 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
3145 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
3146 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
3147 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
3148 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
3149 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
3150 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003151 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003152 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
3153 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
3154 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
3155 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003156 {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS,
3157 splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003158 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003159 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003160 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003161 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
3162 _Py_swapcase__doc__},
3163 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003164 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003165 translate__doc__},
3166 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
3167 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
3168 {NULL}
3169};
3170
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003171PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00003172"bytearray(iterable_of_ints) -> bytearray\n\
3173bytearray(string, encoding[, errors]) -> bytearray\n\
3174bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray\n\
3175bytearray(memory_view) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003176\n\
3177Construct an mutable bytearray object from:\n\
3178 - an iterable yielding integers in range(256)\n\
3179 - a text string encoded using the specified encoding\n\
3180 - a bytes or a bytearray object\n\
3181 - any object implementing the buffer API.\n\
3182\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00003183bytearray(int) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003184\n\
3185Construct a zero-initialized bytearray of the given length.");
3186
3187
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003188static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003189
3190PyTypeObject PyByteArray_Type = {
3191 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3192 "bytearray",
3193 sizeof(PyByteArrayObject),
3194 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003195 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003196 0, /* tp_print */
3197 0, /* tp_getattr */
3198 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003199 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003200 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003201 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003202 &bytearray_as_sequence, /* tp_as_sequence */
3203 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003204 0, /* tp_hash */
3205 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003206 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003207 PyObject_GenericGetAttr, /* tp_getattro */
3208 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003209 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003210 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003211 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003212 0, /* tp_traverse */
3213 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003214 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003215 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003216 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003217 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003218 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003219 0, /* tp_members */
3220 0, /* tp_getset */
3221 0, /* tp_base */
3222 0, /* tp_dict */
3223 0, /* tp_descr_get */
3224 0, /* tp_descr_set */
3225 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003226 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003227 PyType_GenericAlloc, /* tp_alloc */
3228 PyType_GenericNew, /* tp_new */
3229 PyObject_Del, /* tp_free */
3230};
3231
3232/*********************** Bytes Iterator ****************************/
3233
3234typedef struct {
3235 PyObject_HEAD
3236 Py_ssize_t it_index;
3237 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
3238} bytesiterobject;
3239
3240static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003241bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003242{
3243 _PyObject_GC_UNTRACK(it);
3244 Py_XDECREF(it->it_seq);
3245 PyObject_GC_Del(it);
3246}
3247
3248static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003249bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003250{
3251 Py_VISIT(it->it_seq);
3252 return 0;
3253}
3254
3255static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003256bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003257{
3258 PyByteArrayObject *seq;
3259 PyObject *item;
3260
3261 assert(it != NULL);
3262 seq = it->it_seq;
3263 if (seq == NULL)
3264 return NULL;
3265 assert(PyByteArray_Check(seq));
3266
3267 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
3268 item = PyLong_FromLong(
3269 (unsigned char)seq->ob_bytes[it->it_index]);
3270 if (item != NULL)
3271 ++it->it_index;
3272 return item;
3273 }
3274
3275 Py_DECREF(seq);
3276 it->it_seq = NULL;
3277 return NULL;
3278}
3279
3280static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003281bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003282{
3283 Py_ssize_t len = 0;
3284 if (it->it_seq)
3285 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3286 return PyLong_FromSsize_t(len);
3287}
3288
3289PyDoc_STRVAR(length_hint_doc,
3290 "Private method returning an estimate of len(list(it)).");
3291
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003292static PyMethodDef bytearrayiter_methods[] = {
3293 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003294 length_hint_doc},
3295 {NULL, NULL} /* sentinel */
3296};
3297
3298PyTypeObject PyByteArrayIter_Type = {
3299 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3300 "bytearray_iterator", /* tp_name */
3301 sizeof(bytesiterobject), /* tp_basicsize */
3302 0, /* tp_itemsize */
3303 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003304 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003305 0, /* tp_print */
3306 0, /* tp_getattr */
3307 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003308 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003309 0, /* tp_repr */
3310 0, /* tp_as_number */
3311 0, /* tp_as_sequence */
3312 0, /* tp_as_mapping */
3313 0, /* tp_hash */
3314 0, /* tp_call */
3315 0, /* tp_str */
3316 PyObject_GenericGetAttr, /* tp_getattro */
3317 0, /* tp_setattro */
3318 0, /* tp_as_buffer */
3319 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3320 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003321 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003322 0, /* tp_clear */
3323 0, /* tp_richcompare */
3324 0, /* tp_weaklistoffset */
3325 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003326 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3327 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003328 0,
3329};
3330
3331static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003332bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003333{
3334 bytesiterobject *it;
3335
3336 if (!PyByteArray_Check(seq)) {
3337 PyErr_BadInternalCall();
3338 return NULL;
3339 }
3340 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3341 if (it == NULL)
3342 return NULL;
3343 it->it_index = 0;
3344 Py_INCREF(seq);
3345 it->it_seq = (PyByteArrayObject *)seq;
3346 _PyObject_GC_TRACK(it);
3347 return (PyObject *)it;
3348}