blob: 308bd07c5148f9bf91b57226ff0cb429868f5191 [file] [log] [blame]
Christian Heimes44720832008-05-26 13:01:01 +00001/* PyBytes (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;
9
10void
11PyByteArray_Fini(void)
12{
13 Py_CLEAR(nullbytes);
14}
15
16int
17PyByteArray_Init(void)
18{
19 nullbytes = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
20 if (nullbytes == NULL)
21 return 0;
22 nullbytes->ob_bytes = NULL;
23 Py_SIZE(nullbytes) = nullbytes->ob_alloc = 0;
24 nullbytes->ob_exports = 0;
25 return 1;
26}
27
28/* end nullbytes support */
29
30/* Helpers */
31
32static int
33_getbytevalue(PyObject* arg, int *value)
34{
35 long face_value;
36
Georg Brandl3e483f62008-07-16 22:57:41 +000037 if (PyBytes_CheckExact(arg)) {
Christian Heimes44720832008-05-26 13:01:01 +000038 if (Py_SIZE(arg) != 1) {
39 PyErr_SetString(PyExc_ValueError, "string must be of size 1");
40 return 0;
41 }
Georg Brandl3e483f62008-07-16 22:57:41 +000042 *value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
43 return 1;
44 }
45 else if (PyInt_Check(arg) || PyLong_Check(arg)) {
46 face_value = PyLong_AsLong(arg);
Christian Heimes44720832008-05-26 13:01:01 +000047 }
48 else {
Georg Brandl3e483f62008-07-16 22:57:41 +000049 PyObject *index = PyNumber_Index(arg);
50 if (index == NULL) {
51 PyErr_Format(PyExc_TypeError,
52 "an integer or string of size 1 is required");
53 return 0;
54 }
55 face_value = PyLong_AsLong(index);
56 Py_DECREF(index);
57 }
Georg Brandl3e483f62008-07-16 22:57:41 +000058
59 if (face_value < 0 || face_value >= 256) {
Georg Brandl3238a3e2008-07-16 23:17:46 +000060 /* this includes the OverflowError in case the long is too large */
Georg Brandl3e483f62008-07-16 22:57:41 +000061 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Christian Heimes44720832008-05-26 13:01:01 +000062 return 0;
63 }
64
65 *value = face_value;
66 return 1;
67}
68
69static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000070bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000071{
72 if ( index != 0 ) {
73 PyErr_SetString(PyExc_SystemError,
74 "accessing non-existent bytes segment");
75 return -1;
76 }
77 *ptr = (void *)self->ob_bytes;
78 return Py_SIZE(self);
79}
80
81static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000082bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000083{
84 if ( index != 0 ) {
85 PyErr_SetString(PyExc_SystemError,
86 "accessing non-existent bytes segment");
87 return -1;
88 }
89 *ptr = (void *)self->ob_bytes;
90 return Py_SIZE(self);
91}
92
93static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000094bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
Christian Heimes44720832008-05-26 13:01:01 +000095{
96 if ( lenp )
97 *lenp = Py_SIZE(self);
98 return 1;
99}
100
101static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +0000102bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
Christian Heimes44720832008-05-26 13:01:01 +0000103{
104 if ( index != 0 ) {
105 PyErr_SetString(PyExc_SystemError,
106 "accessing non-existent bytes segment");
107 return -1;
108 }
109 *ptr = self->ob_bytes;
110 return Py_SIZE(self);
111}
112
113static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000114bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes44720832008-05-26 13:01:01 +0000115{
116 int ret;
117 void *ptr;
118 if (view == NULL) {
119 obj->ob_exports++;
120 return 0;
121 }
122 if (obj->ob_bytes == NULL)
123 ptr = "";
124 else
125 ptr = obj->ob_bytes;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000126 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
Christian Heimes44720832008-05-26 13:01:01 +0000127 if (ret >= 0) {
128 obj->ob_exports++;
129 }
130 return ret;
131}
132
133static void
Benjamin Petersond6720012009-04-18 15:31:34 +0000134bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes44720832008-05-26 13:01:01 +0000135{
136 obj->ob_exports--;
137}
138
139static Py_ssize_t
140_getbuffer(PyObject *obj, Py_buffer *view)
141{
142 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
143
144 if (buffer == NULL || buffer->bf_getbuffer == NULL)
145 {
146 PyErr_Format(PyExc_TypeError,
147 "Type %.100s doesn't support the buffer API",
148 Py_TYPE(obj)->tp_name);
149 return -1;
150 }
151
152 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
153 return -1;
154 return view->len;
155}
156
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000157static int
158_canresize(PyByteArrayObject *self)
159{
160 if (self->ob_exports > 0) {
161 PyErr_SetString(PyExc_BufferError,
162 "Existing exports of data: object cannot be re-sized");
163 return 0;
164 }
165 return 1;
166}
167
Christian Heimes44720832008-05-26 13:01:01 +0000168/* Direct API functions */
169
170PyObject *
171PyByteArray_FromObject(PyObject *input)
172{
173 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
174 input, NULL);
175}
176
177PyObject *
178PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
179{
180 PyByteArrayObject *new;
181 Py_ssize_t alloc;
182
183 if (size < 0) {
184 PyErr_SetString(PyExc_SystemError,
185 "Negative size passed to PyByteArray_FromStringAndSize");
186 return NULL;
187 }
188
189 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
190 if (new == NULL)
191 return NULL;
192
193 if (size == 0) {
194 new->ob_bytes = NULL;
195 alloc = 0;
196 }
197 else {
198 alloc = size + 1;
199 new->ob_bytes = PyMem_Malloc(alloc);
200 if (new->ob_bytes == NULL) {
201 Py_DECREF(new);
202 return PyErr_NoMemory();
203 }
204 if (bytes != NULL)
205 memcpy(new->ob_bytes, bytes, size);
206 new->ob_bytes[size] = '\0'; /* Trailing null byte */
207 }
208 Py_SIZE(new) = size;
209 new->ob_alloc = alloc;
210 new->ob_exports = 0;
211
212 return (PyObject *)new;
213}
214
215Py_ssize_t
216PyByteArray_Size(PyObject *self)
217{
218 assert(self != NULL);
219 assert(PyByteArray_Check(self));
220
221 return PyByteArray_GET_SIZE(self);
222}
223
224char *
225PyByteArray_AsString(PyObject *self)
226{
227 assert(self != NULL);
228 assert(PyByteArray_Check(self));
229
230 return PyByteArray_AS_STRING(self);
231}
232
233int
234PyByteArray_Resize(PyObject *self, Py_ssize_t size)
235{
236 void *sval;
237 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
238
239 assert(self != NULL);
240 assert(PyByteArray_Check(self));
241 assert(size >= 0);
242
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000243 if (size == Py_SIZE(self)) {
244 return 0;
245 }
246 if (!_canresize((PyByteArrayObject *)self)) {
247 return -1;
248 }
249
Christian Heimes44720832008-05-26 13:01:01 +0000250 if (size < alloc / 2) {
251 /* Major downsize; resize down to exact size */
252 alloc = size + 1;
253 }
254 else if (size < alloc) {
255 /* Within allocated size; quick exit */
256 Py_SIZE(self) = size;
257 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
258 return 0;
259 }
260 else if (size <= alloc * 1.125) {
261 /* Moderate upsize; overallocate similar to list_resize() */
262 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
263 }
264 else {
265 /* Major upsize; resize up to exact size */
266 alloc = size + 1;
267 }
268
Christian Heimes44720832008-05-26 13:01:01 +0000269 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
270 if (sval == NULL) {
271 PyErr_NoMemory();
272 return -1;
273 }
274
275 ((PyByteArrayObject *)self)->ob_bytes = sval;
276 Py_SIZE(self) = size;
277 ((PyByteArrayObject *)self)->ob_alloc = alloc;
278 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
279
280 return 0;
281}
282
283PyObject *
284PyByteArray_Concat(PyObject *a, PyObject *b)
285{
286 Py_ssize_t size;
287 Py_buffer va, vb;
288 PyByteArrayObject *result = NULL;
289
290 va.len = -1;
291 vb.len = -1;
292 if (_getbuffer(a, &va) < 0 ||
293 _getbuffer(b, &vb) < 0) {
294 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
295 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
296 goto done;
297 }
298
299 size = va.len + vb.len;
300 if (size < 0) {
Hirokazu Yamamotoa3e6c972009-03-05 09:34:14 +0000301 PyErr_NoMemory();
Christian Heimes44720832008-05-26 13:01:01 +0000302 goto done;
303 }
304
305 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
306 if (result != NULL) {
307 memcpy(result->ob_bytes, va.buf, va.len);
308 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
309 }
310
311 done:
312 if (va.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000313 PyBuffer_Release(&va);
Christian Heimes44720832008-05-26 13:01:01 +0000314 if (vb.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000315 PyBuffer_Release(&vb);
Christian Heimes44720832008-05-26 13:01:01 +0000316 return (PyObject *)result;
317}
318
319/* Functions stuffed into the type object */
320
321static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +0000322bytearray_length(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000323{
324 return Py_SIZE(self);
325}
326
327static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000328bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes44720832008-05-26 13:01:01 +0000329{
330 Py_ssize_t mysize;
331 Py_ssize_t size;
332 Py_buffer vo;
333
334 if (_getbuffer(other, &vo) < 0) {
335 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
336 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
337 return NULL;
338 }
339
340 mysize = Py_SIZE(self);
341 size = mysize + vo.len;
342 if (size < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000343 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000344 return PyErr_NoMemory();
345 }
346 if (size < self->ob_alloc) {
347 Py_SIZE(self) = size;
348 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
349 }
350 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000351 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000352 return NULL;
353 }
354 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000355 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000356 Py_INCREF(self);
357 return (PyObject *)self;
358}
359
360static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000361bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000362{
363 PyByteArrayObject *result;
364 Py_ssize_t mysize;
365 Py_ssize_t size;
366
367 if (count < 0)
368 count = 0;
369 mysize = Py_SIZE(self);
370 size = mysize * count;
371 if (count != 0 && size / count != mysize)
372 return PyErr_NoMemory();
373 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
374 if (result != NULL && size != 0) {
375 if (mysize == 1)
376 memset(result->ob_bytes, self->ob_bytes[0], size);
377 else {
378 Py_ssize_t i;
379 for (i = 0; i < count; i++)
380 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
381 }
382 }
383 return (PyObject *)result;
384}
385
386static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000387bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000388{
389 Py_ssize_t mysize;
390 Py_ssize_t size;
391
392 if (count < 0)
393 count = 0;
394 mysize = Py_SIZE(self);
395 size = mysize * count;
396 if (count != 0 && size / count != mysize)
397 return PyErr_NoMemory();
398 if (size < self->ob_alloc) {
399 Py_SIZE(self) = size;
400 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
401 }
402 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
403 return NULL;
404
405 if (mysize == 1)
406 memset(self->ob_bytes, self->ob_bytes[0], size);
407 else {
408 Py_ssize_t i;
409 for (i = 1; i < count; i++)
410 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
411 }
412
413 Py_INCREF(self);
414 return (PyObject *)self;
415}
416
417static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000418bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes44720832008-05-26 13:01:01 +0000419{
420 if (i < 0)
421 i += Py_SIZE(self);
422 if (i < 0 || i >= Py_SIZE(self)) {
423 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
424 return NULL;
425 }
426 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
427}
428
429static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000430bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes44720832008-05-26 13:01:01 +0000431{
Georg Brandl3e483f62008-07-16 22:57:41 +0000432 if (PyIndex_Check(index)) {
433 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000434
435 if (i == -1 && PyErr_Occurred())
436 return NULL;
437
438 if (i < 0)
439 i += PyByteArray_GET_SIZE(self);
440
441 if (i < 0 || i >= Py_SIZE(self)) {
442 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
443 return NULL;
444 }
445 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
446 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000447 else if (PySlice_Check(index)) {
Christian Heimes44720832008-05-26 13:01:01 +0000448 Py_ssize_t start, stop, step, slicelength, cur, i;
Georg Brandl3e483f62008-07-16 22:57:41 +0000449 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes44720832008-05-26 13:01:01 +0000450 PyByteArray_GET_SIZE(self),
451 &start, &stop, &step, &slicelength) < 0) {
452 return NULL;
453 }
454
455 if (slicelength <= 0)
456 return PyByteArray_FromStringAndSize("", 0);
457 else if (step == 1) {
458 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
459 slicelength);
460 }
461 else {
462 char *source_buf = PyByteArray_AS_STRING(self);
463 char *result_buf = (char *)PyMem_Malloc(slicelength);
464 PyObject *result;
465
466 if (result_buf == NULL)
467 return PyErr_NoMemory();
468
469 for (cur = start, i = 0; i < slicelength;
470 cur += step, i++) {
471 result_buf[i] = source_buf[cur];
472 }
473 result = PyByteArray_FromStringAndSize(result_buf, slicelength);
474 PyMem_Free(result_buf);
475 return result;
476 }
477 }
478 else {
479 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
480 return NULL;
481 }
482}
483
484static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000485bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes44720832008-05-26 13:01:01 +0000486 PyObject *values)
487{
488 Py_ssize_t avail, needed;
489 void *bytes;
490 Py_buffer vbytes;
491 int res = 0;
492
493 vbytes.len = -1;
494 if (values == (PyObject *)self) {
495 /* Make a copy and call this function recursively */
496 int err;
497 values = PyByteArray_FromObject(values);
498 if (values == NULL)
499 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000500 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes44720832008-05-26 13:01:01 +0000501 Py_DECREF(values);
502 return err;
503 }
504 if (values == NULL) {
505 /* del b[lo:hi] */
506 bytes = NULL;
507 needed = 0;
508 }
509 else {
510 if (_getbuffer(values, &vbytes) < 0) {
511 PyErr_Format(PyExc_TypeError,
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000512 "can't set bytearray slice from %.100s",
Christian Heimes44720832008-05-26 13:01:01 +0000513 Py_TYPE(values)->tp_name);
514 return -1;
515 }
516 needed = vbytes.len;
517 bytes = vbytes.buf;
518 }
519
520 if (lo < 0)
521 lo = 0;
522 if (hi < lo)
523 hi = lo;
524 if (hi > Py_SIZE(self))
525 hi = Py_SIZE(self);
526
527 avail = hi - lo;
528 if (avail < 0)
529 lo = hi = avail = 0;
530
531 if (avail != needed) {
532 if (avail > needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000533 if (!_canresize(self)) {
534 res = -1;
535 goto finish;
536 }
Christian Heimes44720832008-05-26 13:01:01 +0000537 /*
538 0 lo hi old_size
539 | |<----avail----->|<-----tomove------>|
540 | |<-needed->|<-----tomove------>|
541 0 lo new_hi new_size
542 */
543 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
544 Py_SIZE(self) - hi);
545 }
546 /* XXX(nnorwitz): need to verify this can't overflow! */
547 if (PyByteArray_Resize((PyObject *)self,
548 Py_SIZE(self) + needed - avail) < 0) {
549 res = -1;
550 goto finish;
551 }
552 if (avail < needed) {
553 /*
554 0 lo hi old_size
555 | |<-avail->|<-----tomove------>|
556 | |<----needed---->|<-----tomove------>|
557 0 lo new_hi new_size
558 */
559 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
560 Py_SIZE(self) - lo - needed);
561 }
562 }
563
564 if (needed > 0)
565 memcpy(self->ob_bytes + lo, bytes, needed);
566
567
568 finish:
569 if (vbytes.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000570 PyBuffer_Release(&vbytes);
Christian Heimes44720832008-05-26 13:01:01 +0000571 return res;
572}
573
574static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000575bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes44720832008-05-26 13:01:01 +0000576{
577 int ival;
578
579 if (i < 0)
580 i += Py_SIZE(self);
581
582 if (i < 0 || i >= Py_SIZE(self)) {
583 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
584 return -1;
585 }
586
587 if (value == NULL)
Benjamin Petersond6720012009-04-18 15:31:34 +0000588 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes44720832008-05-26 13:01:01 +0000589
590 if (!_getbytevalue(value, &ival))
591 return -1;
592
593 self->ob_bytes[i] = ival;
594 return 0;
595}
596
597static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000598bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes44720832008-05-26 13:01:01 +0000599{
600 Py_ssize_t start, stop, step, slicelen, needed;
601 char *bytes;
602
Georg Brandl3e483f62008-07-16 22:57:41 +0000603 if (PyIndex_Check(index)) {
604 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000605
606 if (i == -1 && PyErr_Occurred())
607 return -1;
608
609 if (i < 0)
610 i += PyByteArray_GET_SIZE(self);
611
612 if (i < 0 || i >= Py_SIZE(self)) {
613 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
614 return -1;
615 }
616
617 if (values == NULL) {
618 /* Fall through to slice assignment */
619 start = i;
620 stop = i + 1;
621 step = 1;
622 slicelen = 1;
623 }
624 else {
Georg Brandl3e483f62008-07-16 22:57:41 +0000625 int ival;
626 if (!_getbytevalue(values, &ival))
Christian Heimes44720832008-05-26 13:01:01 +0000627 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000628 self->ob_bytes[i] = (char)ival;
629 return 0;
630 }
631 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000632 else if (PySlice_Check(index)) {
633 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes44720832008-05-26 13:01:01 +0000634 PyByteArray_GET_SIZE(self),
635 &start, &stop, &step, &slicelen) < 0) {
636 return -1;
637 }
638 }
639 else {
640 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
641 return -1;
642 }
643
644 if (values == NULL) {
645 bytes = NULL;
646 needed = 0;
647 }
648 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
649 /* Make a copy an call this function recursively */
650 int err;
651 values = PyByteArray_FromObject(values);
652 if (values == NULL)
653 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000654 err = bytearray_ass_subscript(self, index, values);
Christian Heimes44720832008-05-26 13:01:01 +0000655 Py_DECREF(values);
656 return err;
657 }
658 else {
659 assert(PyByteArray_Check(values));
660 bytes = ((PyByteArrayObject *)values)->ob_bytes;
661 needed = Py_SIZE(values);
662 }
663 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
664 if ((step < 0 && start < stop) ||
665 (step > 0 && start > stop))
666 stop = start;
667 if (step == 1) {
668 if (slicelen != needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000669 if (!_canresize(self))
670 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000671 if (slicelen > needed) {
672 /*
673 0 start stop old_size
674 | |<---slicelen--->|<-----tomove------>|
675 | |<-needed->|<-----tomove------>|
676 0 lo new_hi new_size
677 */
678 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
679 Py_SIZE(self) - stop);
680 }
681 if (PyByteArray_Resize((PyObject *)self,
682 Py_SIZE(self) + needed - slicelen) < 0)
683 return -1;
684 if (slicelen < needed) {
685 /*
686 0 lo hi old_size
687 | |<-avail->|<-----tomove------>|
688 | |<----needed---->|<-----tomove------>|
689 0 lo new_hi new_size
690 */
691 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
692 Py_SIZE(self) - start - needed);
693 }
694 }
695
696 if (needed > 0)
697 memcpy(self->ob_bytes + start, bytes, needed);
698
699 return 0;
700 }
701 else {
702 if (needed == 0) {
703 /* Delete slice */
704 Py_ssize_t cur, i;
705
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000706 if (!_canresize(self))
707 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000708 if (step < 0) {
709 stop = start + 1;
710 start = stop + step * (slicelen - 1) - 1;
711 step = -step;
712 }
713 for (cur = start, i = 0;
714 i < slicelen; cur += step, i++) {
715 Py_ssize_t lim = step - 1;
716
717 if (cur + step >= PyByteArray_GET_SIZE(self))
718 lim = PyByteArray_GET_SIZE(self) - cur - 1;
719
720 memmove(self->ob_bytes + cur - i,
721 self->ob_bytes + cur + 1, lim);
722 }
723 /* Move the tail of the bytes, in one chunk */
724 cur = start + slicelen*step;
725 if (cur < PyByteArray_GET_SIZE(self)) {
726 memmove(self->ob_bytes + cur - slicelen,
727 self->ob_bytes + cur,
728 PyByteArray_GET_SIZE(self) - cur);
729 }
730 if (PyByteArray_Resize((PyObject *)self,
731 PyByteArray_GET_SIZE(self) - slicelen) < 0)
732 return -1;
733
734 return 0;
735 }
736 else {
737 /* Assign slice */
738 Py_ssize_t cur, i;
739
740 if (needed != slicelen) {
741 PyErr_Format(PyExc_ValueError,
742 "attempt to assign bytes of size %zd "
743 "to extended slice of size %zd",
744 needed, slicelen);
745 return -1;
746 }
747 for (cur = start, i = 0; i < slicelen; cur += step, i++)
748 self->ob_bytes[cur] = bytes[i];
749 return 0;
750 }
751 }
752}
753
754static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000755bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes44720832008-05-26 13:01:01 +0000756{
757 static char *kwlist[] = {"source", "encoding", "errors", 0};
758 PyObject *arg = NULL;
759 const char *encoding = NULL;
760 const char *errors = NULL;
761 Py_ssize_t count;
762 PyObject *it;
763 PyObject *(*iternext)(PyObject *);
764
765 if (Py_SIZE(self) != 0) {
766 /* Empty previous contents (yes, do this first of all!) */
767 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
768 return -1;
769 }
770
771 /* Parse arguments */
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000772 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes44720832008-05-26 13:01:01 +0000773 &arg, &encoding, &errors))
774 return -1;
775
776 /* Make a quick exit if no first argument */
777 if (arg == NULL) {
778 if (encoding != NULL || errors != NULL) {
779 PyErr_SetString(PyExc_TypeError,
780 "encoding or errors without sequence argument");
781 return -1;
782 }
783 return 0;
784 }
785
786 if (PyBytes_Check(arg)) {
787 PyObject *new, *encoded;
788 if (encoding != NULL) {
789 encoded = PyCodec_Encode(arg, encoding, errors);
790 if (encoded == NULL)
791 return -1;
792 assert(PyBytes_Check(encoded));
793 }
794 else {
795 encoded = arg;
796 Py_INCREF(arg);
797 }
Benjamin Petersond6720012009-04-18 15:31:34 +0000798 new = bytearray_iconcat(self, arg);
Christian Heimes44720832008-05-26 13:01:01 +0000799 Py_DECREF(encoded);
800 if (new == NULL)
801 return -1;
802 Py_DECREF(new);
803 return 0;
804 }
805
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000806#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +0000807 if (PyUnicode_Check(arg)) {
808 /* Encode via the codec registry */
809 PyObject *encoded, *new;
810 if (encoding == NULL) {
811 PyErr_SetString(PyExc_TypeError,
812 "unicode argument without an encoding");
813 return -1;
814 }
815 encoded = PyCodec_Encode(arg, encoding, errors);
816 if (encoded == NULL)
817 return -1;
818 assert(PyBytes_Check(encoded));
Benjamin Petersond6720012009-04-18 15:31:34 +0000819 new = bytearray_iconcat(self, encoded);
Christian Heimes44720832008-05-26 13:01:01 +0000820 Py_DECREF(encoded);
821 if (new == NULL)
822 return -1;
823 Py_DECREF(new);
824 return 0;
825 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000826#endif
Christian Heimes44720832008-05-26 13:01:01 +0000827
828 /* If it's not unicode, there can't be encoding or errors */
829 if (encoding != NULL || errors != NULL) {
830 PyErr_SetString(PyExc_TypeError,
831 "encoding or errors without a string argument");
832 return -1;
833 }
834
835 /* Is it an int? */
836 count = PyNumber_AsSsize_t(arg, PyExc_ValueError);
837 if (count == -1 && PyErr_Occurred())
838 PyErr_Clear();
839 else {
840 if (count < 0) {
841 PyErr_SetString(PyExc_ValueError, "negative count");
842 return -1;
843 }
844 if (count > 0) {
845 if (PyByteArray_Resize((PyObject *)self, count))
846 return -1;
847 memset(self->ob_bytes, 0, count);
848 }
849 return 0;
850 }
851
852 /* Use the buffer API */
853 if (PyObject_CheckBuffer(arg)) {
854 Py_ssize_t size;
855 Py_buffer view;
856 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
857 return -1;
858 size = view.len;
859 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
860 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
861 goto fail;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000862 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000863 return 0;
864 fail:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000865 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000866 return -1;
867 }
868
869 /* XXX Optimize this if the arguments is a list, tuple */
870
871 /* Get the iterator */
872 it = PyObject_GetIter(arg);
873 if (it == NULL)
874 return -1;
875 iternext = *Py_TYPE(it)->tp_iternext;
876
877 /* Run the iterator to exhaustion */
878 for (;;) {
879 PyObject *item;
Georg Brandl3e758462008-07-16 23:10:05 +0000880 int rc, value;
Christian Heimes44720832008-05-26 13:01:01 +0000881
882 /* Get the next item */
883 item = iternext(it);
884 if (item == NULL) {
885 if (PyErr_Occurred()) {
886 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
887 goto error;
888 PyErr_Clear();
889 }
890 break;
891 }
892
893 /* Interpret it as an int (__index__) */
Georg Brandl3e758462008-07-16 23:10:05 +0000894 rc = _getbytevalue(item, &value);
Christian Heimes44720832008-05-26 13:01:01 +0000895 Py_DECREF(item);
Georg Brandl3e758462008-07-16 23:10:05 +0000896 if (!rc)
Christian Heimes44720832008-05-26 13:01:01 +0000897 goto error;
898
Christian Heimes44720832008-05-26 13:01:01 +0000899 /* Append the byte */
900 if (Py_SIZE(self) < self->ob_alloc)
901 Py_SIZE(self)++;
902 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
903 goto error;
904 self->ob_bytes[Py_SIZE(self)-1] = value;
905 }
906
907 /* Clean up and return success */
908 Py_DECREF(it);
909 return 0;
910
911 error:
912 /* Error handling when it != NULL */
913 Py_DECREF(it);
914 return -1;
915}
916
917/* Mostly copied from string_repr, but without the
918 "smart quote" functionality. */
919static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000920bytearray_repr(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000921{
922 static const char *hexdigits = "0123456789abcdef";
923 const char *quote_prefix = "bytearray(b";
924 const char *quote_postfix = ")";
925 Py_ssize_t length = Py_SIZE(self);
926 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
927 size_t newsize = 14 + 4 * length;
928 PyObject *v;
929 if (newsize > PY_SSIZE_T_MAX || newsize / 4 - 3 != length) {
930 PyErr_SetString(PyExc_OverflowError,
931 "bytearray object is too large to make repr");
932 return NULL;
933 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000934 v = PyString_FromStringAndSize(NULL, newsize);
Christian Heimes44720832008-05-26 13:01:01 +0000935 if (v == NULL) {
936 return NULL;
937 }
938 else {
939 register Py_ssize_t i;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000940 register char c;
941 register char *p;
Christian Heimes44720832008-05-26 13:01:01 +0000942 int quote;
943
944 /* Figure out which quote to use; single is preferred */
945 quote = '\'';
946 {
947 char *test, *start;
948 start = PyByteArray_AS_STRING(self);
949 for (test = start; test < start+length; ++test) {
950 if (*test == '"') {
951 quote = '\''; /* back to single */
952 goto decided;
953 }
954 else if (*test == '\'')
955 quote = '"';
956 }
957 decided:
958 ;
959 }
960
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000961 p = PyString_AS_STRING(v);
Christian Heimes44720832008-05-26 13:01:01 +0000962 while (*quote_prefix)
963 *p++ = *quote_prefix++;
964 *p++ = quote;
965
966 for (i = 0; i < length; i++) {
967 /* There's at least enough room for a hex escape
968 and a closing quote. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000969 assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
Christian Heimes44720832008-05-26 13:01:01 +0000970 c = self->ob_bytes[i];
971 if (c == '\'' || c == '\\')
972 *p++ = '\\', *p++ = c;
973 else if (c == '\t')
974 *p++ = '\\', *p++ = 't';
975 else if (c == '\n')
976 *p++ = '\\', *p++ = 'n';
977 else if (c == '\r')
978 *p++ = '\\', *p++ = 'r';
979 else if (c == 0)
980 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
981 else if (c < ' ' || c >= 0x7f) {
982 *p++ = '\\';
983 *p++ = 'x';
984 *p++ = hexdigits[(c & 0xf0) >> 4];
985 *p++ = hexdigits[c & 0xf];
986 }
987 else
988 *p++ = c;
989 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000990 assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
Christian Heimes44720832008-05-26 13:01:01 +0000991 *p++ = quote;
992 while (*quote_postfix) {
993 *p++ = *quote_postfix++;
994 }
995 *p = '\0';
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000996 if (_PyString_Resize(&v, (p - PyString_AS_STRING(v)))) {
Christian Heimes44720832008-05-26 13:01:01 +0000997 Py_DECREF(v);
998 return NULL;
999 }
1000 return v;
1001 }
1002}
1003
1004static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001005bytearray_str(PyObject *op)
Christian Heimes44720832008-05-26 13:01:01 +00001006{
1007#if 0
1008 if (Py_BytesWarningFlag) {
1009 if (PyErr_WarnEx(PyExc_BytesWarning,
1010 "str() on a bytearray instance", 1))
1011 return NULL;
1012 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001013 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes44720832008-05-26 13:01:01 +00001014#endif
1015 return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
1016}
1017
1018static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001019bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes44720832008-05-26 13:01:01 +00001020{
1021 Py_ssize_t self_size, other_size;
1022 Py_buffer self_bytes, other_bytes;
1023 PyObject *res;
1024 Py_ssize_t minsize;
1025 int cmp;
1026
1027 /* Bytes can be compared to anything that supports the (binary)
1028 buffer API. Except that a comparison with Unicode is always an
1029 error, even if the comparison is for equality. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001030#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00001031 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1032 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
1033 if (Py_BytesWarningFlag && op == Py_EQ) {
1034 if (PyErr_WarnEx(PyExc_BytesWarning,
Ezio Melottid2342082010-01-14 11:34:10 +00001035 "Comparison between bytearray and string", 1))
Christian Heimes44720832008-05-26 13:01:01 +00001036 return NULL;
1037 }
1038
1039 Py_INCREF(Py_NotImplemented);
1040 return Py_NotImplemented;
1041 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001042#endif
Christian Heimes44720832008-05-26 13:01:01 +00001043
1044 self_size = _getbuffer(self, &self_bytes);
1045 if (self_size < 0) {
1046 PyErr_Clear();
1047 Py_INCREF(Py_NotImplemented);
1048 return Py_NotImplemented;
1049 }
1050
1051 other_size = _getbuffer(other, &other_bytes);
1052 if (other_size < 0) {
1053 PyErr_Clear();
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001054 PyBuffer_Release(&self_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001055 Py_INCREF(Py_NotImplemented);
1056 return Py_NotImplemented;
1057 }
1058
1059 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1060 /* Shortcut: if the lengths differ, the objects differ */
1061 cmp = (op == Py_NE);
1062 }
1063 else {
1064 minsize = self_size;
1065 if (other_size < minsize)
1066 minsize = other_size;
1067
1068 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1069 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1070
1071 if (cmp == 0) {
1072 if (self_size < other_size)
1073 cmp = -1;
1074 else if (self_size > other_size)
1075 cmp = 1;
1076 }
1077
1078 switch (op) {
1079 case Py_LT: cmp = cmp < 0; break;
1080 case Py_LE: cmp = cmp <= 0; break;
1081 case Py_EQ: cmp = cmp == 0; break;
1082 case Py_NE: cmp = cmp != 0; break;
1083 case Py_GT: cmp = cmp > 0; break;
1084 case Py_GE: cmp = cmp >= 0; break;
1085 }
1086 }
1087
1088 res = cmp ? Py_True : Py_False;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001089 PyBuffer_Release(&self_bytes);
1090 PyBuffer_Release(&other_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001091 Py_INCREF(res);
1092 return res;
1093}
1094
1095static void
Benjamin Petersond6720012009-04-18 15:31:34 +00001096bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00001097{
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001098 if (self->ob_exports > 0) {
1099 PyErr_SetString(PyExc_SystemError,
Georg Brandl517cfdc2009-04-05 13:16:35 +00001100 "deallocated bytearray object has exported buffers");
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001101 PyErr_Print();
1102 }
Christian Heimes44720832008-05-26 13:01:01 +00001103 if (self->ob_bytes != 0) {
1104 PyMem_Free(self->ob_bytes);
1105 }
1106 Py_TYPE(self)->tp_free((PyObject *)self);
1107}
1108
1109
1110/* -------------------------------------------------------------------- */
1111/* Methods */
1112
1113#define STRINGLIB_CHAR char
Christian Heimes44720832008-05-26 13:01:01 +00001114#define STRINGLIB_LEN PyByteArray_GET_SIZE
1115#define STRINGLIB_STR PyByteArray_AS_STRING
1116#define STRINGLIB_NEW PyByteArray_FromStringAndSize
1117#define STRINGLIB_EMPTY nullbytes
Antoine Pitrou64672132010-01-13 07:55:48 +00001118#define STRINGLIB_ISSPACE Py_ISSPACE
1119#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes44720832008-05-26 13:01:01 +00001120#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1121#define STRINGLIB_MUTABLE 1
1122
1123#include "stringlib/fastsearch.h"
1124#include "stringlib/count.h"
1125#include "stringlib/find.h"
1126#include "stringlib/partition.h"
Antoine Pitrou64672132010-01-13 07:55:48 +00001127#include "stringlib/split.h"
Christian Heimes44720832008-05-26 13:01:01 +00001128#include "stringlib/ctype.h"
1129#include "stringlib/transmogrify.h"
1130
1131
1132/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1133were copied from the old char* style string object. */
1134
Antoine Pitrou64672132010-01-13 07:55:48 +00001135/* helper macro to fixup start/end slice values */
1136#define ADJUST_INDICES(start, end, len) \
1137 if (end > len) \
1138 end = len; \
1139 else if (end < 0) { \
1140 end += len; \
1141 if (end < 0) \
1142 end = 0; \
1143 } \
1144 if (start < 0) { \
1145 start += len; \
1146 if (start < 0) \
1147 start = 0; \
1148 }
Christian Heimes44720832008-05-26 13:01:01 +00001149
1150Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Petersond6720012009-04-18 15:31:34 +00001151bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes44720832008-05-26 13:01:01 +00001152{
1153 PyObject *subobj;
1154 Py_buffer subbuf;
1155 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1156 Py_ssize_t res;
1157
1158 if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
1159 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1160 return -2;
1161 if (_getbuffer(subobj, &subbuf) < 0)
1162 return -2;
1163 if (dir > 0)
1164 res = stringlib_find_slice(
1165 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1166 subbuf.buf, subbuf.len, start, end);
1167 else
1168 res = stringlib_rfind_slice(
1169 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1170 subbuf.buf, subbuf.len, start, end);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001171 PyBuffer_Release(&subbuf);
Christian Heimes44720832008-05-26 13:01:01 +00001172 return res;
1173}
1174
1175PyDoc_STRVAR(find__doc__,
1176"B.find(sub [,start [,end]]) -> int\n\
1177\n\
1178Return the lowest index in B where subsection sub is found,\n\
1179such that sub is contained within s[start,end]. Optional\n\
1180arguments start and end are interpreted as in slice notation.\n\
1181\n\
1182Return -1 on failure.");
1183
1184static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001185bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001186{
Benjamin Petersond6720012009-04-18 15:31:34 +00001187 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001188 if (result == -2)
1189 return NULL;
1190 return PyInt_FromSsize_t(result);
1191}
1192
1193PyDoc_STRVAR(count__doc__,
1194"B.count(sub [,start [,end]]) -> int\n\
1195\n\
1196Return the number of non-overlapping occurrences of subsection sub in\n\
1197bytes B[start:end]. Optional arguments start and end are interpreted\n\
1198as in slice notation.");
1199
1200static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001201bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001202{
1203 PyObject *sub_obj;
1204 const char *str = PyByteArray_AS_STRING(self);
1205 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1206 Py_buffer vsub;
1207 PyObject *count_obj;
1208
1209 if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1210 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1211 return NULL;
1212
1213 if (_getbuffer(sub_obj, &vsub) < 0)
1214 return NULL;
1215
Antoine Pitrou64672132010-01-13 07:55:48 +00001216 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes44720832008-05-26 13:01:01 +00001217
1218 count_obj = PyInt_FromSsize_t(
Antoine Pitrou64672132010-01-13 07:55:48 +00001219 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes44720832008-05-26 13:01:01 +00001220 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001221 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00001222 return count_obj;
1223}
1224
1225
1226PyDoc_STRVAR(index__doc__,
1227"B.index(sub [,start [,end]]) -> int\n\
1228\n\
1229Like B.find() but raise ValueError when the subsection is not found.");
1230
1231static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001232bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001233{
Benjamin Petersond6720012009-04-18 15:31:34 +00001234 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001235 if (result == -2)
1236 return NULL;
1237 if (result == -1) {
1238 PyErr_SetString(PyExc_ValueError,
1239 "subsection not found");
1240 return NULL;
1241 }
1242 return PyInt_FromSsize_t(result);
1243}
1244
1245
1246PyDoc_STRVAR(rfind__doc__,
1247"B.rfind(sub [,start [,end]]) -> int\n\
1248\n\
1249Return the highest index in B where subsection sub is found,\n\
1250such that sub is contained within s[start,end]. Optional\n\
1251arguments start and end are interpreted as in slice notation.\n\
1252\n\
1253Return -1 on failure.");
1254
1255static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001256bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001257{
Benjamin Petersond6720012009-04-18 15:31:34 +00001258 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001259 if (result == -2)
1260 return NULL;
1261 return PyInt_FromSsize_t(result);
1262}
1263
1264
1265PyDoc_STRVAR(rindex__doc__,
1266"B.rindex(sub [,start [,end]]) -> int\n\
1267\n\
1268Like B.rfind() but raise ValueError when the subsection is not found.");
1269
1270static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001271bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001272{
Benjamin Petersond6720012009-04-18 15:31:34 +00001273 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001274 if (result == -2)
1275 return NULL;
1276 if (result == -1) {
1277 PyErr_SetString(PyExc_ValueError,
1278 "subsection not found");
1279 return NULL;
1280 }
1281 return PyInt_FromSsize_t(result);
1282}
1283
1284
1285static int
Benjamin Petersond6720012009-04-18 15:31:34 +00001286bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00001287{
1288 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1289 if (ival == -1 && PyErr_Occurred()) {
1290 Py_buffer varg;
1291 int pos;
1292 PyErr_Clear();
1293 if (_getbuffer(arg, &varg) < 0)
1294 return -1;
1295 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1296 varg.buf, varg.len, 0);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001297 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00001298 return pos >= 0;
1299 }
1300 if (ival < 0 || ival >= 256) {
1301 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1302 return -1;
1303 }
1304
1305 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1306}
1307
1308
1309/* Matches the end (direction >= 0) or start (direction < 0) of self
1310 * against substr, using the start and end arguments. Returns
1311 * -1 on error, 0 if not found and 1 if found.
1312 */
1313Py_LOCAL(int)
Benjamin Petersond6720012009-04-18 15:31:34 +00001314_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes44720832008-05-26 13:01:01 +00001315 Py_ssize_t end, int direction)
1316{
1317 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1318 const char* str;
1319 Py_buffer vsubstr;
1320 int rv = 0;
1321
1322 str = PyByteArray_AS_STRING(self);
1323
1324 if (_getbuffer(substr, &vsubstr) < 0)
1325 return -1;
1326
Antoine Pitrou64672132010-01-13 07:55:48 +00001327 ADJUST_INDICES(start, end, len);
Christian Heimes44720832008-05-26 13:01:01 +00001328
1329 if (direction < 0) {
1330 /* startswith */
1331 if (start+vsubstr.len > len) {
1332 goto done;
1333 }
1334 } else {
1335 /* endswith */
1336 if (end-start < vsubstr.len || start > len) {
1337 goto done;
1338 }
1339
1340 if (end-vsubstr.len > start)
1341 start = end - vsubstr.len;
1342 }
1343 if (end-start >= vsubstr.len)
1344 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1345
1346done:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001347 PyBuffer_Release(&vsubstr);
Christian Heimes44720832008-05-26 13:01:01 +00001348 return rv;
1349}
1350
1351
1352PyDoc_STRVAR(startswith__doc__,
1353"B.startswith(prefix [,start [,end]]) -> bool\n\
1354\n\
1355Return True if B starts with the specified prefix, False otherwise.\n\
1356With optional start, test B beginning at that position.\n\
1357With optional end, stop comparing B at that position.\n\
1358prefix can also be a tuple of strings to try.");
1359
1360static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001361bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001362{
1363 Py_ssize_t start = 0;
1364 Py_ssize_t end = PY_SSIZE_T_MAX;
1365 PyObject *subobj;
1366 int result;
1367
1368 if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
1369 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1370 return NULL;
1371 if (PyTuple_Check(subobj)) {
1372 Py_ssize_t i;
1373 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001374 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001375 PyTuple_GET_ITEM(subobj, i),
1376 start, end, -1);
1377 if (result == -1)
1378 return NULL;
1379 else if (result) {
1380 Py_RETURN_TRUE;
1381 }
1382 }
1383 Py_RETURN_FALSE;
1384 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001385 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001386 if (result == -1)
1387 return NULL;
1388 else
1389 return PyBool_FromLong(result);
1390}
1391
1392PyDoc_STRVAR(endswith__doc__,
1393"B.endswith(suffix [,start [,end]]) -> bool\n\
1394\n\
1395Return True if B ends with the specified suffix, False otherwise.\n\
1396With optional start, test B beginning at that position.\n\
1397With optional end, stop comparing B at that position.\n\
1398suffix can also be a tuple of strings to try.");
1399
1400static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001401bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001402{
1403 Py_ssize_t start = 0;
1404 Py_ssize_t end = PY_SSIZE_T_MAX;
1405 PyObject *subobj;
1406 int result;
1407
1408 if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
1409 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1410 return NULL;
1411 if (PyTuple_Check(subobj)) {
1412 Py_ssize_t i;
1413 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001414 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001415 PyTuple_GET_ITEM(subobj, i),
1416 start, end, +1);
1417 if (result == -1)
1418 return NULL;
1419 else if (result) {
1420 Py_RETURN_TRUE;
1421 }
1422 }
1423 Py_RETURN_FALSE;
1424 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001425 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001426 if (result == -1)
1427 return NULL;
1428 else
1429 return PyBool_FromLong(result);
1430}
1431
1432
1433PyDoc_STRVAR(translate__doc__,
1434"B.translate(table[, deletechars]) -> bytearray\n\
1435\n\
1436Return a copy of B, where all characters occurring in the\n\
1437optional argument deletechars are removed, and the remaining\n\
1438characters have been mapped through the given translation\n\
1439table, which must be a bytes object of length 256.");
1440
1441static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001442bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001443{
1444 register char *input, *output;
1445 register const char *table;
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001446 register Py_ssize_t i, c;
Christian Heimes44720832008-05-26 13:01:01 +00001447 PyObject *input_obj = (PyObject*)self;
1448 const char *output_start;
1449 Py_ssize_t inlen;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001450 PyObject *result = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001451 int trans_table[256];
Georg Brandl6425a2f2008-12-28 11:54:53 +00001452 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001453 Py_buffer vtable, vdel;
1454
1455 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1456 &tableobj, &delobj))
1457 return NULL;
1458
Georg Brandl6425a2f2008-12-28 11:54:53 +00001459 if (tableobj == Py_None) {
1460 table = NULL;
1461 tableobj = NULL;
1462 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00001463 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001464 } else {
1465 if (vtable.len != 256) {
1466 PyErr_SetString(PyExc_ValueError,
1467 "translation table must be 256 characters long");
Georg Brandlec812ca2009-07-22 11:57:15 +00001468 PyBuffer_Release(&vtable);
1469 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001470 }
1471 table = (const char*)vtable.buf;
Christian Heimes44720832008-05-26 13:01:01 +00001472 }
1473
1474 if (delobj != NULL) {
1475 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandlec812ca2009-07-22 11:57:15 +00001476 if (tableobj != NULL)
1477 PyBuffer_Release(&vtable);
1478 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001479 }
1480 }
1481 else {
1482 vdel.buf = NULL;
1483 vdel.len = 0;
1484 }
1485
Christian Heimes44720832008-05-26 13:01:01 +00001486 inlen = PyByteArray_GET_SIZE(input_obj);
1487 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1488 if (result == NULL)
1489 goto done;
1490 output_start = output = PyByteArray_AsString(result);
1491 input = PyByteArray_AS_STRING(input_obj);
1492
Georg Brandl6425a2f2008-12-28 11:54:53 +00001493 if (vdel.len == 0 && table != NULL) {
Christian Heimes44720832008-05-26 13:01:01 +00001494 /* If no deletions are required, use faster code */
1495 for (i = inlen; --i >= 0; ) {
1496 c = Py_CHARMASK(*input++);
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001497 *output++ = table[c];
Christian Heimes44720832008-05-26 13:01:01 +00001498 }
Christian Heimes44720832008-05-26 13:01:01 +00001499 goto done;
1500 }
Georg Brandl6425a2f2008-12-28 11:54:53 +00001501
1502 if (table == NULL) {
1503 for (i = 0; i < 256; i++)
1504 trans_table[i] = Py_CHARMASK(i);
1505 } else {
1506 for (i = 0; i < 256; i++)
1507 trans_table[i] = Py_CHARMASK(table[i]);
1508 }
Christian Heimes44720832008-05-26 13:01:01 +00001509
1510 for (i = 0; i < vdel.len; i++)
1511 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1512
1513 for (i = inlen; --i >= 0; ) {
1514 c = Py_CHARMASK(*input++);
1515 if (trans_table[c] != -1)
1516 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1517 continue;
Christian Heimes44720832008-05-26 13:01:01 +00001518 }
1519 /* Fix the size of the resulting string */
1520 if (inlen > 0)
1521 PyByteArray_Resize(result, output - output_start);
1522
1523done:
Georg Brandl6425a2f2008-12-28 11:54:53 +00001524 if (tableobj != NULL)
1525 PyBuffer_Release(&vtable);
Christian Heimes44720832008-05-26 13:01:01 +00001526 if (delobj != NULL)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001527 PyBuffer_Release(&vdel);
Christian Heimes44720832008-05-26 13:01:01 +00001528 return result;
1529}
1530
1531
Christian Heimes44720832008-05-26 13:01:01 +00001532/* find and count characters and substrings */
1533
1534#define findchar(target, target_len, c) \
1535 ((char *)memchr((const void *)(target), c, target_len))
1536
Christian Heimes44720832008-05-26 13:01:01 +00001537
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001538/* Bytes ops must return a string, create a copy */
Christian Heimes44720832008-05-26 13:01:01 +00001539Py_LOCAL(PyByteArrayObject *)
1540return_self(PyByteArrayObject *self)
1541{
Christian Heimes44720832008-05-26 13:01:01 +00001542 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1543 PyByteArray_AS_STRING(self),
1544 PyByteArray_GET_SIZE(self));
1545}
1546
1547Py_LOCAL_INLINE(Py_ssize_t)
1548countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1549{
1550 Py_ssize_t count=0;
1551 const char *start=target;
1552 const char *end=target+target_len;
1553
1554 while ( (start=findchar(start, end-start, c)) != NULL ) {
1555 count++;
1556 if (count >= maxcount)
1557 break;
1558 start += 1;
1559 }
1560 return count;
1561}
1562
Christian Heimes44720832008-05-26 13:01:01 +00001563
1564/* Algorithms for different cases of string replacement */
1565
1566/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1567Py_LOCAL(PyByteArrayObject *)
1568replace_interleave(PyByteArrayObject *self,
1569 const char *to_s, Py_ssize_t to_len,
1570 Py_ssize_t maxcount)
1571{
1572 char *self_s, *result_s;
1573 Py_ssize_t self_len, result_len;
1574 Py_ssize_t count, i, product;
1575 PyByteArrayObject *result;
1576
1577 self_len = PyByteArray_GET_SIZE(self);
1578
1579 /* 1 at the end plus 1 after every character */
1580 count = self_len+1;
1581 if (maxcount < count)
1582 count = maxcount;
1583
1584 /* Check for overflow */
1585 /* result_len = count * to_len + self_len; */
1586 product = count * to_len;
1587 if (product / to_len != count) {
1588 PyErr_SetString(PyExc_OverflowError,
1589 "replace string is too long");
1590 return NULL;
1591 }
1592 result_len = product + self_len;
1593 if (result_len < 0) {
1594 PyErr_SetString(PyExc_OverflowError,
1595 "replace string is too long");
1596 return NULL;
1597 }
1598
1599 if (! (result = (PyByteArrayObject *)
1600 PyByteArray_FromStringAndSize(NULL, result_len)) )
1601 return NULL;
1602
1603 self_s = PyByteArray_AS_STRING(self);
1604 result_s = PyByteArray_AS_STRING(result);
1605
1606 /* TODO: special case single character, which doesn't need memcpy */
1607
1608 /* Lay the first one down (guaranteed this will occur) */
1609 Py_MEMCPY(result_s, to_s, to_len);
1610 result_s += to_len;
1611 count -= 1;
1612
1613 for (i=0; i<count; i++) {
1614 *result_s++ = *self_s++;
1615 Py_MEMCPY(result_s, to_s, to_len);
1616 result_s += to_len;
1617 }
1618
1619 /* Copy the rest of the original string */
1620 Py_MEMCPY(result_s, self_s, self_len-i);
1621
1622 return result;
1623}
1624
1625/* Special case for deleting a single character */
1626/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1627Py_LOCAL(PyByteArrayObject *)
1628replace_delete_single_character(PyByteArrayObject *self,
1629 char from_c, Py_ssize_t maxcount)
1630{
1631 char *self_s, *result_s;
1632 char *start, *next, *end;
1633 Py_ssize_t self_len, result_len;
1634 Py_ssize_t count;
1635 PyByteArrayObject *result;
1636
1637 self_len = PyByteArray_GET_SIZE(self);
1638 self_s = PyByteArray_AS_STRING(self);
1639
1640 count = countchar(self_s, self_len, from_c, maxcount);
1641 if (count == 0) {
1642 return return_self(self);
1643 }
1644
1645 result_len = self_len - count; /* from_len == 1 */
1646 assert(result_len>=0);
1647
1648 if ( (result = (PyByteArrayObject *)
1649 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1650 return NULL;
1651 result_s = PyByteArray_AS_STRING(result);
1652
1653 start = self_s;
1654 end = self_s + self_len;
1655 while (count-- > 0) {
1656 next = findchar(start, end-start, from_c);
1657 if (next == NULL)
1658 break;
1659 Py_MEMCPY(result_s, start, next-start);
1660 result_s += (next-start);
1661 start = next+1;
1662 }
1663 Py_MEMCPY(result_s, start, end-start);
1664
1665 return result;
1666}
1667
1668/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1669
1670Py_LOCAL(PyByteArrayObject *)
1671replace_delete_substring(PyByteArrayObject *self,
1672 const char *from_s, Py_ssize_t from_len,
1673 Py_ssize_t maxcount)
1674{
1675 char *self_s, *result_s;
1676 char *start, *next, *end;
1677 Py_ssize_t self_len, result_len;
1678 Py_ssize_t count, offset;
1679 PyByteArrayObject *result;
1680
1681 self_len = PyByteArray_GET_SIZE(self);
1682 self_s = PyByteArray_AS_STRING(self);
1683
Antoine Pitrou64672132010-01-13 07:55:48 +00001684 count = stringlib_count(self_s, self_len,
1685 from_s, from_len,
1686 maxcount);
Christian Heimes44720832008-05-26 13:01:01 +00001687
1688 if (count == 0) {
1689 /* no matches */
1690 return return_self(self);
1691 }
1692
1693 result_len = self_len - (count * from_len);
1694 assert (result_len>=0);
1695
1696 if ( (result = (PyByteArrayObject *)
1697 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1698 return NULL;
1699
1700 result_s = PyByteArray_AS_STRING(result);
1701
1702 start = self_s;
1703 end = self_s + self_len;
1704 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001705 offset = stringlib_find(start, end-start,
1706 from_s, from_len,
1707 0);
Christian Heimes44720832008-05-26 13:01:01 +00001708 if (offset == -1)
1709 break;
1710 next = start + offset;
1711
1712 Py_MEMCPY(result_s, start, next-start);
1713
1714 result_s += (next-start);
1715 start = next+from_len;
1716 }
1717 Py_MEMCPY(result_s, start, end-start);
1718 return result;
1719}
1720
1721/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1722Py_LOCAL(PyByteArrayObject *)
1723replace_single_character_in_place(PyByteArrayObject *self,
1724 char from_c, char to_c,
1725 Py_ssize_t maxcount)
1726{
1727 char *self_s, *result_s, *start, *end, *next;
1728 Py_ssize_t self_len;
1729 PyByteArrayObject *result;
1730
1731 /* The result string will be the same size */
1732 self_s = PyByteArray_AS_STRING(self);
1733 self_len = PyByteArray_GET_SIZE(self);
1734
1735 next = findchar(self_s, self_len, from_c);
1736
1737 if (next == NULL) {
1738 /* No matches; return the original bytes */
1739 return return_self(self);
1740 }
1741
1742 /* Need to make a new bytes */
1743 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1744 if (result == NULL)
1745 return NULL;
1746 result_s = PyByteArray_AS_STRING(result);
1747 Py_MEMCPY(result_s, self_s, self_len);
1748
1749 /* change everything in-place, starting with this one */
1750 start = result_s + (next-self_s);
1751 *start = to_c;
1752 start++;
1753 end = result_s + self_len;
1754
1755 while (--maxcount > 0) {
1756 next = findchar(start, end-start, from_c);
1757 if (next == NULL)
1758 break;
1759 *next = to_c;
1760 start = next+1;
1761 }
1762
1763 return result;
1764}
1765
1766/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1767Py_LOCAL(PyByteArrayObject *)
1768replace_substring_in_place(PyByteArrayObject *self,
1769 const char *from_s, Py_ssize_t from_len,
1770 const char *to_s, Py_ssize_t to_len,
1771 Py_ssize_t maxcount)
1772{
1773 char *result_s, *start, *end;
1774 char *self_s;
1775 Py_ssize_t self_len, offset;
1776 PyByteArrayObject *result;
1777
1778 /* The result bytes will be the same size */
1779
1780 self_s = PyByteArray_AS_STRING(self);
1781 self_len = PyByteArray_GET_SIZE(self);
1782
Antoine Pitrou64672132010-01-13 07:55:48 +00001783 offset = stringlib_find(self_s, self_len,
1784 from_s, from_len,
1785 0);
Christian Heimes44720832008-05-26 13:01:01 +00001786 if (offset == -1) {
1787 /* No matches; return the original bytes */
1788 return return_self(self);
1789 }
1790
1791 /* Need to make a new bytes */
1792 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1793 if (result == NULL)
1794 return NULL;
1795 result_s = PyByteArray_AS_STRING(result);
1796 Py_MEMCPY(result_s, self_s, self_len);
1797
1798 /* change everything in-place, starting with this one */
1799 start = result_s + offset;
1800 Py_MEMCPY(start, to_s, from_len);
1801 start += from_len;
1802 end = result_s + self_len;
1803
1804 while ( --maxcount > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001805 offset = stringlib_find(start, end-start,
1806 from_s, from_len,
1807 0);
Christian Heimes44720832008-05-26 13:01:01 +00001808 if (offset==-1)
1809 break;
1810 Py_MEMCPY(start+offset, to_s, from_len);
1811 start += offset+from_len;
1812 }
1813
1814 return result;
1815}
1816
1817/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1818Py_LOCAL(PyByteArrayObject *)
1819replace_single_character(PyByteArrayObject *self,
1820 char from_c,
1821 const char *to_s, Py_ssize_t to_len,
1822 Py_ssize_t maxcount)
1823{
1824 char *self_s, *result_s;
1825 char *start, *next, *end;
1826 Py_ssize_t self_len, result_len;
1827 Py_ssize_t count, product;
1828 PyByteArrayObject *result;
1829
1830 self_s = PyByteArray_AS_STRING(self);
1831 self_len = PyByteArray_GET_SIZE(self);
1832
1833 count = countchar(self_s, self_len, from_c, maxcount);
1834 if (count == 0) {
1835 /* no matches, return unchanged */
1836 return return_self(self);
1837 }
1838
1839 /* use the difference between current and new, hence the "-1" */
1840 /* result_len = self_len + count * (to_len-1) */
1841 product = count * (to_len-1);
1842 if (product / (to_len-1) != count) {
1843 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1844 return NULL;
1845 }
1846 result_len = self_len + product;
1847 if (result_len < 0) {
1848 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1849 return NULL;
1850 }
1851
1852 if ( (result = (PyByteArrayObject *)
1853 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1854 return NULL;
1855 result_s = PyByteArray_AS_STRING(result);
1856
1857 start = self_s;
1858 end = self_s + self_len;
1859 while (count-- > 0) {
1860 next = findchar(start, end-start, from_c);
1861 if (next == NULL)
1862 break;
1863
1864 if (next == start) {
1865 /* replace with the 'to' */
1866 Py_MEMCPY(result_s, to_s, to_len);
1867 result_s += to_len;
1868 start += 1;
1869 } else {
1870 /* copy the unchanged old then the 'to' */
1871 Py_MEMCPY(result_s, start, next-start);
1872 result_s += (next-start);
1873 Py_MEMCPY(result_s, to_s, to_len);
1874 result_s += to_len;
1875 start = next+1;
1876 }
1877 }
1878 /* Copy the remainder of the remaining bytes */
1879 Py_MEMCPY(result_s, start, end-start);
1880
1881 return result;
1882}
1883
1884/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1885Py_LOCAL(PyByteArrayObject *)
1886replace_substring(PyByteArrayObject *self,
1887 const char *from_s, Py_ssize_t from_len,
1888 const char *to_s, Py_ssize_t to_len,
1889 Py_ssize_t maxcount)
1890{
1891 char *self_s, *result_s;
1892 char *start, *next, *end;
1893 Py_ssize_t self_len, result_len;
1894 Py_ssize_t count, offset, product;
1895 PyByteArrayObject *result;
1896
1897 self_s = PyByteArray_AS_STRING(self);
1898 self_len = PyByteArray_GET_SIZE(self);
1899
Antoine Pitrou64672132010-01-13 07:55:48 +00001900 count = stringlib_count(self_s, self_len,
1901 from_s, from_len,
1902 maxcount);
1903
Christian Heimes44720832008-05-26 13:01:01 +00001904 if (count == 0) {
1905 /* no matches, return unchanged */
1906 return return_self(self);
1907 }
1908
1909 /* Check for overflow */
1910 /* result_len = self_len + count * (to_len-from_len) */
1911 product = count * (to_len-from_len);
1912 if (product / (to_len-from_len) != count) {
1913 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1914 return NULL;
1915 }
1916 result_len = self_len + product;
1917 if (result_len < 0) {
1918 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1919 return NULL;
1920 }
1921
1922 if ( (result = (PyByteArrayObject *)
1923 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1924 return NULL;
1925 result_s = PyByteArray_AS_STRING(result);
1926
1927 start = self_s;
1928 end = self_s + self_len;
1929 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001930 offset = stringlib_find(start, end-start,
1931 from_s, from_len,
1932 0);
Christian Heimes44720832008-05-26 13:01:01 +00001933 if (offset == -1)
1934 break;
1935 next = start+offset;
1936 if (next == start) {
1937 /* replace with the 'to' */
1938 Py_MEMCPY(result_s, to_s, to_len);
1939 result_s += to_len;
1940 start += from_len;
1941 } else {
1942 /* copy the unchanged old then the 'to' */
1943 Py_MEMCPY(result_s, start, next-start);
1944 result_s += (next-start);
1945 Py_MEMCPY(result_s, to_s, to_len);
1946 result_s += to_len;
1947 start = next+from_len;
1948 }
1949 }
1950 /* Copy the remainder of the remaining bytes */
1951 Py_MEMCPY(result_s, start, end-start);
1952
1953 return result;
1954}
1955
1956
1957Py_LOCAL(PyByteArrayObject *)
1958replace(PyByteArrayObject *self,
1959 const char *from_s, Py_ssize_t from_len,
1960 const char *to_s, Py_ssize_t to_len,
1961 Py_ssize_t maxcount)
1962{
1963 if (maxcount < 0) {
1964 maxcount = PY_SSIZE_T_MAX;
1965 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1966 /* nothing to do; return the original bytes */
1967 return return_self(self);
1968 }
1969
1970 if (maxcount == 0 ||
1971 (from_len == 0 && to_len == 0)) {
1972 /* nothing to do; return the original bytes */
1973 return return_self(self);
1974 }
1975
1976 /* Handle zero-length special cases */
1977
1978 if (from_len == 0) {
1979 /* insert the 'to' bytes everywhere. */
1980 /* >>> "Python".replace("", ".") */
1981 /* '.P.y.t.h.o.n.' */
1982 return replace_interleave(self, to_s, to_len, maxcount);
1983 }
1984
1985 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1986 /* point for an empty self bytes to generate a non-empty bytes */
1987 /* Special case so the remaining code always gets a non-empty bytes */
1988 if (PyByteArray_GET_SIZE(self) == 0) {
1989 return return_self(self);
1990 }
1991
1992 if (to_len == 0) {
1993 /* delete all occurances of 'from' bytes */
1994 if (from_len == 1) {
1995 return replace_delete_single_character(
1996 self, from_s[0], maxcount);
1997 } else {
1998 return replace_delete_substring(self, from_s, from_len, maxcount);
1999 }
2000 }
2001
2002 /* Handle special case where both bytes have the same length */
2003
2004 if (from_len == to_len) {
2005 if (from_len == 1) {
2006 return replace_single_character_in_place(
2007 self,
2008 from_s[0],
2009 to_s[0],
2010 maxcount);
2011 } else {
2012 return replace_substring_in_place(
2013 self, from_s, from_len, to_s, to_len, maxcount);
2014 }
2015 }
2016
2017 /* Otherwise use the more generic algorithms */
2018 if (from_len == 1) {
2019 return replace_single_character(self, from_s[0],
2020 to_s, to_len, maxcount);
2021 } else {
2022 /* len('from')>=2, len('to')>=1 */
2023 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2024 }
2025}
2026
2027
2028PyDoc_STRVAR(replace__doc__,
2029"B.replace(old, new[, count]) -> bytes\n\
2030\n\
2031Return a copy of B with all occurrences of subsection\n\
2032old replaced by new. If the optional argument count is\n\
2033given, only the first count occurrences are replaced.");
2034
2035static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002036bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002037{
2038 Py_ssize_t count = -1;
2039 PyObject *from, *to, *res;
2040 Py_buffer vfrom, vto;
2041
2042 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2043 return NULL;
2044
2045 if (_getbuffer(from, &vfrom) < 0)
2046 return NULL;
2047 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002048 PyBuffer_Release(&vfrom);
Christian Heimes44720832008-05-26 13:01:01 +00002049 return NULL;
2050 }
2051
2052 res = (PyObject *)replace((PyByteArrayObject *) self,
2053 vfrom.buf, vfrom.len,
2054 vto.buf, vto.len, count);
2055
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002056 PyBuffer_Release(&vfrom);
2057 PyBuffer_Release(&vto);
Christian Heimes44720832008-05-26 13:01:01 +00002058 return res;
2059}
2060
Christian Heimes44720832008-05-26 13:01:01 +00002061PyDoc_STRVAR(split__doc__,
2062"B.split([sep[, maxsplit]]) -> list of bytearray\n\
2063\n\
2064Return a list of the sections in B, using sep as the delimiter.\n\
2065If sep is not given, B is split on ASCII whitespace characters\n\
2066(space, tab, return, newline, formfeed, vertical tab).\n\
2067If maxsplit is given, at most maxsplit splits are done.");
2068
2069static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002070bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002071{
Antoine Pitrou64672132010-01-13 07:55:48 +00002072 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2073 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002074 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002075 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002076 Py_buffer vsub;
Christian Heimes44720832008-05-26 13:01:01 +00002077
2078 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2079 return NULL;
2080 if (maxsplit < 0)
2081 maxsplit = PY_SSIZE_T_MAX;
2082
2083 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002084 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002085
2086 if (_getbuffer(subobj, &vsub) < 0)
2087 return NULL;
2088 sub = vsub.buf;
2089 n = vsub.len;
2090
Antoine Pitrou64672132010-01-13 07:55:48 +00002091 list = stringlib_split(
2092 (PyObject*) self, s, len, sub, n, maxsplit
2093 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002094 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002095 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002096}
2097
2098PyDoc_STRVAR(partition__doc__,
2099"B.partition(sep) -> (head, sep, tail)\n\
2100\n\
2101Searches for the separator sep in B, and returns the part before it,\n\
2102the separator itself, and the part after it. If the separator is not\n\
2103found, returns B and two empty bytearray objects.");
2104
2105static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002106bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002107{
2108 PyObject *bytesep, *result;
2109
2110 bytesep = PyByteArray_FromObject(sep_obj);
2111 if (! bytesep)
2112 return NULL;
2113
2114 result = stringlib_partition(
2115 (PyObject*) self,
2116 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2117 bytesep,
2118 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2119 );
2120
2121 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002122 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002123}
2124
2125PyDoc_STRVAR(rpartition__doc__,
2126"B.rpartition(sep) -> (tail, sep, head)\n\
2127\n\
2128Searches for the separator sep in B, starting at the end of B,\n\
2129and returns the part before it, the separator itself, and the\n\
2130part after it. If the separator is not found, returns two empty\n\
2131bytearray objects and B.");
2132
2133static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002134bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002135{
2136 PyObject *bytesep, *result;
2137
2138 bytesep = PyByteArray_FromObject(sep_obj);
2139 if (! bytesep)
2140 return NULL;
2141
2142 result = stringlib_rpartition(
2143 (PyObject*) self,
2144 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2145 bytesep,
2146 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2147 );
2148
2149 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002150 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002151}
2152
2153PyDoc_STRVAR(rsplit__doc__,
2154"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2155\n\
2156Return a list of the sections in B, using sep as the delimiter,\n\
2157starting at the end of B and working to the front.\n\
2158If sep is not given, B is split on ASCII whitespace characters\n\
2159(space, tab, return, newline, formfeed, vertical tab).\n\
2160If maxsplit is given, at most maxsplit splits are done.");
2161
2162static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002163bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002164{
Antoine Pitrou64672132010-01-13 07:55:48 +00002165 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2166 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002167 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002168 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002169 Py_buffer vsub;
2170
2171 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2172 return NULL;
2173 if (maxsplit < 0)
2174 maxsplit = PY_SSIZE_T_MAX;
2175
2176 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002177 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002178
2179 if (_getbuffer(subobj, &vsub) < 0)
2180 return NULL;
2181 sub = vsub.buf;
2182 n = vsub.len;
2183
Antoine Pitrou64672132010-01-13 07:55:48 +00002184 list = stringlib_rsplit(
2185 (PyObject*) self, s, len, sub, n, maxsplit
2186 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002187 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002188 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002189}
2190
2191PyDoc_STRVAR(reverse__doc__,
2192"B.reverse() -> None\n\
2193\n\
2194Reverse the order of the values in B in place.");
2195static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002196bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes44720832008-05-26 13:01:01 +00002197{
2198 char swap, *head, *tail;
2199 Py_ssize_t i, j, n = Py_SIZE(self);
2200
2201 j = n / 2;
2202 head = self->ob_bytes;
2203 tail = head + n - 1;
2204 for (i = 0; i < j; i++) {
2205 swap = *head;
2206 *head++ = *tail;
2207 *tail-- = swap;
2208 }
2209
2210 Py_RETURN_NONE;
2211}
2212
2213PyDoc_STRVAR(insert__doc__,
2214"B.insert(index, int) -> None\n\
2215\n\
2216Insert a single item into the bytearray before the given index.");
2217static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002218bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002219{
Georg Brandl3e483f62008-07-16 22:57:41 +00002220 PyObject *value;
2221 int ival;
Christian Heimes44720832008-05-26 13:01:01 +00002222 Py_ssize_t where, n = Py_SIZE(self);
2223
Georg Brandl3e483f62008-07-16 22:57:41 +00002224 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes44720832008-05-26 13:01:01 +00002225 return NULL;
2226
2227 if (n == PY_SSIZE_T_MAX) {
2228 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002229 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002230 return NULL;
2231 }
Georg Brandl3e483f62008-07-16 22:57:41 +00002232 if (!_getbytevalue(value, &ival))
Christian Heimes44720832008-05-26 13:01:01 +00002233 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002234 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2235 return NULL;
2236
2237 if (where < 0) {
2238 where += n;
2239 if (where < 0)
2240 where = 0;
2241 }
2242 if (where > n)
2243 where = n;
2244 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl3e483f62008-07-16 22:57:41 +00002245 self->ob_bytes[where] = ival;
Christian Heimes44720832008-05-26 13:01:01 +00002246
2247 Py_RETURN_NONE;
2248}
2249
2250PyDoc_STRVAR(append__doc__,
2251"B.append(int) -> None\n\
2252\n\
2253Append a single item to the end of B.");
2254static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002255bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002256{
2257 int value;
2258 Py_ssize_t n = Py_SIZE(self);
2259
2260 if (! _getbytevalue(arg, &value))
2261 return NULL;
2262 if (n == PY_SSIZE_T_MAX) {
2263 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002264 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002265 return NULL;
2266 }
2267 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2268 return NULL;
2269
2270 self->ob_bytes[n] = value;
2271
2272 Py_RETURN_NONE;
2273}
2274
2275PyDoc_STRVAR(extend__doc__,
2276"B.extend(iterable int) -> None\n\
2277\n\
2278Append all the elements from the iterator or sequence to the\n\
2279end of B.");
2280static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002281bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002282{
Benjamin Petersond6720012009-04-18 15:31:34 +00002283 PyObject *it, *item, *bytearray_obj;
Christian Heimes44720832008-05-26 13:01:01 +00002284 Py_ssize_t buf_size = 0, len = 0;
2285 int value;
2286 char *buf;
2287
Benjamin Petersond6720012009-04-18 15:31:34 +00002288 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes44720832008-05-26 13:01:01 +00002289 if (PyObject_CheckBuffer(arg)) {
Benjamin Petersond6720012009-04-18 15:31:34 +00002290 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002291 return NULL;
2292
2293 Py_RETURN_NONE;
2294 }
2295
2296 it = PyObject_GetIter(arg);
2297 if (it == NULL)
2298 return NULL;
2299
2300 /* Try to determine the length of the argument. 32 is abitrary. */
2301 buf_size = _PyObject_LengthHint(arg, 32);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002302 if (buf_size == -1) {
2303 Py_DECREF(it);
2304 return NULL;
2305 }
Christian Heimes44720832008-05-26 13:01:01 +00002306
Benjamin Petersond6720012009-04-18 15:31:34 +00002307 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2308 if (bytearray_obj == NULL)
Christian Heimes44720832008-05-26 13:01:01 +00002309 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002310 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002311
2312 while ((item = PyIter_Next(it)) != NULL) {
2313 if (! _getbytevalue(item, &value)) {
2314 Py_DECREF(item);
2315 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002316 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002317 return NULL;
2318 }
2319 buf[len++] = value;
2320 Py_DECREF(item);
2321
2322 if (len >= buf_size) {
2323 buf_size = len + (len >> 1) + 1;
Benjamin Petersond6720012009-04-18 15:31:34 +00002324 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00002325 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002326 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002327 return NULL;
2328 }
2329 /* Recompute the `buf' pointer, since the resizing operation may
2330 have invalidated it. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002331 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002332 }
2333 }
2334 Py_DECREF(it);
2335
2336 /* Resize down to exact size. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002337 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2338 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002339 return NULL;
2340 }
2341
Benjamin Petersond6720012009-04-18 15:31:34 +00002342 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002343 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002344 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002345
2346 Py_RETURN_NONE;
2347}
2348
2349PyDoc_STRVAR(pop__doc__,
2350"B.pop([index]) -> int\n\
2351\n\
2352Remove and return a single item from B. If no index\n\
Andrew M. Kuchlingd8972642008-06-21 13:29:12 +00002353argument is given, will pop the last value.");
Christian Heimes44720832008-05-26 13:01:01 +00002354static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002355bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002356{
2357 int value;
2358 Py_ssize_t where = -1, n = Py_SIZE(self);
2359
2360 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2361 return NULL;
2362
2363 if (n == 0) {
2364 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002365 "cannot pop an empty bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002366 return NULL;
2367 }
2368 if (where < 0)
2369 where += Py_SIZE(self);
2370 if (where < 0 || where >= Py_SIZE(self)) {
2371 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2372 return NULL;
2373 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002374 if (!_canresize(self))
2375 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002376
2377 value = self->ob_bytes[where];
2378 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2379 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2380 return NULL;
2381
Mark Dickinsonc8a7c7c2009-09-06 10:03:31 +00002382 return PyInt_FromLong((unsigned char)value);
Christian Heimes44720832008-05-26 13:01:01 +00002383}
2384
2385PyDoc_STRVAR(remove__doc__,
2386"B.remove(int) -> None\n\
2387\n\
2388Remove the first occurance of a value in B.");
2389static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002390bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002391{
2392 int value;
2393 Py_ssize_t where, n = Py_SIZE(self);
2394
2395 if (! _getbytevalue(arg, &value))
2396 return NULL;
2397
2398 for (where = 0; where < n; where++) {
2399 if (self->ob_bytes[where] == value)
2400 break;
2401 }
2402 if (where == n) {
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002403 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002404 return NULL;
2405 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002406 if (!_canresize(self))
2407 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002408
2409 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2410 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2411 return NULL;
2412
2413 Py_RETURN_NONE;
2414}
2415
2416/* XXX These two helpers could be optimized if argsize == 1 */
2417
2418static Py_ssize_t
2419lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2420 void *argptr, Py_ssize_t argsize)
2421{
2422 Py_ssize_t i = 0;
2423 while (i < mysize && memchr(argptr, myptr[i], argsize))
2424 i++;
2425 return i;
2426}
2427
2428static Py_ssize_t
2429rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2430 void *argptr, Py_ssize_t argsize)
2431{
2432 Py_ssize_t i = mysize - 1;
2433 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2434 i--;
2435 return i + 1;
2436}
2437
2438PyDoc_STRVAR(strip__doc__,
2439"B.strip([bytes]) -> bytearray\n\
2440\n\
2441Strip leading and trailing bytes contained in the argument.\n\
2442If the argument is omitted, strip ASCII whitespace.");
2443static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002444bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002445{
2446 Py_ssize_t left, right, mysize, argsize;
2447 void *myptr, *argptr;
2448 PyObject *arg = Py_None;
2449 Py_buffer varg;
2450 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2451 return NULL;
2452 if (arg == Py_None) {
2453 argptr = "\t\n\r\f\v ";
2454 argsize = 6;
2455 }
2456 else {
2457 if (_getbuffer(arg, &varg) < 0)
2458 return NULL;
2459 argptr = varg.buf;
2460 argsize = varg.len;
2461 }
2462 myptr = self->ob_bytes;
2463 mysize = Py_SIZE(self);
2464 left = lstrip_helper(myptr, mysize, argptr, argsize);
2465 if (left == mysize)
2466 right = left;
2467 else
2468 right = rstrip_helper(myptr, mysize, argptr, argsize);
2469 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002470 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002471 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2472}
2473
2474PyDoc_STRVAR(lstrip__doc__,
2475"B.lstrip([bytes]) -> bytearray\n\
2476\n\
2477Strip leading bytes contained in the argument.\n\
2478If the argument is omitted, strip leading ASCII whitespace.");
2479static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002480bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002481{
2482 Py_ssize_t left, right, mysize, argsize;
2483 void *myptr, *argptr;
2484 PyObject *arg = Py_None;
2485 Py_buffer varg;
2486 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2487 return NULL;
2488 if (arg == Py_None) {
2489 argptr = "\t\n\r\f\v ";
2490 argsize = 6;
2491 }
2492 else {
2493 if (_getbuffer(arg, &varg) < 0)
2494 return NULL;
2495 argptr = varg.buf;
2496 argsize = varg.len;
2497 }
2498 myptr = self->ob_bytes;
2499 mysize = Py_SIZE(self);
2500 left = lstrip_helper(myptr, mysize, argptr, argsize);
2501 right = mysize;
2502 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002503 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002504 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2505}
2506
2507PyDoc_STRVAR(rstrip__doc__,
2508"B.rstrip([bytes]) -> bytearray\n\
2509\n\
2510Strip trailing bytes contained in the argument.\n\
2511If the argument is omitted, strip trailing ASCII whitespace.");
2512static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002513bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002514{
2515 Py_ssize_t left, right, mysize, argsize;
2516 void *myptr, *argptr;
2517 PyObject *arg = Py_None;
2518 Py_buffer varg;
2519 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2520 return NULL;
2521 if (arg == Py_None) {
2522 argptr = "\t\n\r\f\v ";
2523 argsize = 6;
2524 }
2525 else {
2526 if (_getbuffer(arg, &varg) < 0)
2527 return NULL;
2528 argptr = varg.buf;
2529 argsize = varg.len;
2530 }
2531 myptr = self->ob_bytes;
2532 mysize = Py_SIZE(self);
2533 left = 0;
2534 right = rstrip_helper(myptr, mysize, argptr, argsize);
2535 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002536 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002537 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2538}
2539
2540PyDoc_STRVAR(decode_doc,
2541"B.decode([encoding[, errors]]) -> unicode object.\n\
2542\n\
2543Decodes B using the codec registered for encoding. encoding defaults\n\
2544to the default encoding. errors may be given to set a different error\n\
2545handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2546a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2547as well as any other name registered with codecs.register_error that is\n\
2548able to handle UnicodeDecodeErrors.");
2549
2550static PyObject *
Benjamin Petersondc782b52009-09-18 21:46:21 +00002551bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes44720832008-05-26 13:01:01 +00002552{
2553 const char *encoding = NULL;
2554 const char *errors = NULL;
Benjamin Petersondc782b52009-09-18 21:46:21 +00002555 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes44720832008-05-26 13:01:01 +00002556
Benjamin Petersondc782b52009-09-18 21:46:21 +00002557 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes44720832008-05-26 13:01:01 +00002558 return NULL;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002559 if (encoding == NULL) {
2560#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002561 encoding = PyUnicode_GetDefaultEncoding();
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002562#else
2563 PyErr_SetString(PyExc_ValueError, "no encoding specified");
2564 return NULL;
2565#endif
2566 }
Christian Heimes44720832008-05-26 13:01:01 +00002567 return PyCodec_Decode(self, encoding, errors);
2568}
2569
2570PyDoc_STRVAR(alloc_doc,
2571"B.__alloc__() -> int\n\
2572\n\
2573Returns the number of bytes actually allocated.");
2574
2575static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002576bytearray_alloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002577{
2578 return PyInt_FromSsize_t(self->ob_alloc);
2579}
2580
2581PyDoc_STRVAR(join_doc,
2582"B.join(iterable_of_bytes) -> bytes\n\
2583\n\
2584Concatenates any number of bytearray objects, with B in between each pair.");
2585
2586static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002587bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002588{
2589 PyObject *seq;
2590 Py_ssize_t mysize = Py_SIZE(self);
2591 Py_ssize_t i;
2592 Py_ssize_t n;
2593 PyObject **items;
2594 Py_ssize_t totalsize = 0;
2595 PyObject *result;
2596 char *dest;
2597
2598 seq = PySequence_Fast(it, "can only join an iterable");
2599 if (seq == NULL)
2600 return NULL;
2601 n = PySequence_Fast_GET_SIZE(seq);
2602 items = PySequence_Fast_ITEMS(seq);
2603
2604 /* Compute the total size, and check that they are all bytes */
2605 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2606 for (i = 0; i < n; i++) {
2607 PyObject *obj = items[i];
2608 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2609 PyErr_Format(PyExc_TypeError,
2610 "can only join an iterable of bytes "
2611 "(item %ld has type '%.100s')",
2612 /* XXX %ld isn't right on Win64 */
2613 (long)i, Py_TYPE(obj)->tp_name);
2614 goto error;
2615 }
2616 if (i > 0)
2617 totalsize += mysize;
2618 totalsize += Py_SIZE(obj);
2619 if (totalsize < 0) {
2620 PyErr_NoMemory();
2621 goto error;
2622 }
2623 }
2624
2625 /* Allocate the result, and copy the bytes */
2626 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2627 if (result == NULL)
2628 goto error;
2629 dest = PyByteArray_AS_STRING(result);
2630 for (i = 0; i < n; i++) {
2631 PyObject *obj = items[i];
2632 Py_ssize_t size = Py_SIZE(obj);
2633 char *buf;
2634 if (PyByteArray_Check(obj))
2635 buf = PyByteArray_AS_STRING(obj);
2636 else
2637 buf = PyBytes_AS_STRING(obj);
2638 if (i) {
2639 memcpy(dest, self->ob_bytes, mysize);
2640 dest += mysize;
2641 }
2642 memcpy(dest, buf, size);
2643 dest += size;
2644 }
2645
2646 /* Done */
2647 Py_DECREF(seq);
2648 return result;
2649
2650 /* Error handling */
2651 error:
2652 Py_DECREF(seq);
2653 return NULL;
2654}
2655
Antoine Pitrou64672132010-01-13 07:55:48 +00002656PyDoc_STRVAR(splitlines__doc__,
2657"B.splitlines([keepends]) -> list of lines\n\
2658\n\
2659Return a list of the lines in B, breaking at line boundaries.\n\
2660Line breaks are not included in the resulting list unless keepends\n\
2661is given and true.");
2662
2663static PyObject*
2664bytearray_splitlines(PyObject *self, PyObject *args)
2665{
2666 int keepends = 0;
2667
2668 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2669 return NULL;
2670
2671 return stringlib_splitlines(
2672 (PyObject*) self, PyByteArray_AS_STRING(self),
2673 PyByteArray_GET_SIZE(self), keepends
2674 );
2675}
2676
Christian Heimes44720832008-05-26 13:01:01 +00002677PyDoc_STRVAR(fromhex_doc,
2678"bytearray.fromhex(string) -> bytearray\n\
2679\n\
2680Create a bytearray object from a string of hexadecimal numbers.\n\
2681Spaces between two numbers are accepted.\n\
2682Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2683
2684static int
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002685hex_digit_to_int(char c)
Christian Heimes44720832008-05-26 13:01:01 +00002686{
Eric Smithcac7af62009-04-27 19:04:37 +00002687 if (Py_ISDIGIT(c))
Christian Heimes44720832008-05-26 13:01:01 +00002688 return c - '0';
2689 else {
Eric Smithcac7af62009-04-27 19:04:37 +00002690 if (Py_ISUPPER(c))
2691 c = Py_TOLOWER(c);
Christian Heimes44720832008-05-26 13:01:01 +00002692 if (c >= 'a' && c <= 'f')
2693 return c - 'a' + 10;
2694 }
2695 return -1;
2696}
2697
2698static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002699bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002700{
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002701 PyObject *newbytes;
Christian Heimes44720832008-05-26 13:01:01 +00002702 char *buf;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002703 char *hex;
Christian Heimes44720832008-05-26 13:01:01 +00002704 Py_ssize_t hexlen, byteslen, i, j;
2705 int top, bot;
2706
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002707 if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
Christian Heimes44720832008-05-26 13:01:01 +00002708 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002709 byteslen = hexlen/2; /* This overestimates if there are spaces */
2710 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2711 if (!newbytes)
2712 return NULL;
2713 buf = PyByteArray_AS_STRING(newbytes);
2714 for (i = j = 0; i < hexlen; i += 2) {
2715 /* skip over spaces in the input */
2716 while (hex[i] == ' ')
2717 i++;
2718 if (i >= hexlen)
2719 break;
2720 top = hex_digit_to_int(hex[i]);
2721 bot = hex_digit_to_int(hex[i+1]);
2722 if (top == -1 || bot == -1) {
2723 PyErr_Format(PyExc_ValueError,
2724 "non-hexadecimal number found in "
2725 "fromhex() arg at position %zd", i);
2726 goto error;
2727 }
2728 buf[j++] = (top << 4) + bot;
2729 }
2730 if (PyByteArray_Resize(newbytes, j) < 0)
2731 goto error;
2732 return newbytes;
2733
2734 error:
2735 Py_DECREF(newbytes);
2736 return NULL;
2737}
2738
2739PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2740
2741static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002742bytearray_reduce(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002743{
2744 PyObject *latin1, *dict;
2745 if (self->ob_bytes)
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002746#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002747 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2748 Py_SIZE(self), NULL);
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002749#else
Mark Dickinson9d109742009-10-15 15:18:55 +00002750 latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002751#endif
Christian Heimes44720832008-05-26 13:01:01 +00002752 else
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002753#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002754 latin1 = PyUnicode_FromString("");
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002755#else
2756 latin1 = PyString_FromString("");
2757#endif
Christian Heimes44720832008-05-26 13:01:01 +00002758
2759 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2760 if (dict == NULL) {
2761 PyErr_Clear();
2762 dict = Py_None;
2763 Py_INCREF(dict);
2764 }
2765
2766 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2767}
2768
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002769PyDoc_STRVAR(sizeof_doc,
2770"B.__sizeof__() -> int\n\
2771 \n\
2772Returns the size of B in memory, in bytes");
2773static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002774bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002775{
Georg Brandl517cfdc2009-04-05 13:16:35 +00002776 Py_ssize_t res;
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002777
Georg Brandl517cfdc2009-04-05 13:16:35 +00002778 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2779 return PyInt_FromSsize_t(res);
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002780}
2781
Benjamin Petersond6720012009-04-18 15:31:34 +00002782static PySequenceMethods bytearray_as_sequence = {
2783 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes44720832008-05-26 13:01:01 +00002784 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Petersond6720012009-04-18 15:31:34 +00002785 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2786 (ssizeargfunc)bytearray_getitem, /* sq_item */
2787 0, /* sq_slice */
2788 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2789 0, /* sq_ass_slice */
2790 (objobjproc)bytearray_contains, /* sq_contains */
2791 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2792 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes44720832008-05-26 13:01:01 +00002793};
2794
Benjamin Petersond6720012009-04-18 15:31:34 +00002795static PyMappingMethods bytearray_as_mapping = {
2796 (lenfunc)bytearray_length,
2797 (binaryfunc)bytearray_subscript,
2798 (objobjargproc)bytearray_ass_subscript,
Christian Heimes44720832008-05-26 13:01:01 +00002799};
2800
Benjamin Petersond6720012009-04-18 15:31:34 +00002801static PyBufferProcs bytearray_as_buffer = {
2802 (readbufferproc)bytearray_buffer_getreadbuf,
2803 (writebufferproc)bytearray_buffer_getwritebuf,
2804 (segcountproc)bytearray_buffer_getsegcount,
2805 (charbufferproc)bytearray_buffer_getcharbuf,
2806 (getbufferproc)bytearray_getbuffer,
2807 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes44720832008-05-26 13:01:01 +00002808};
2809
2810static PyMethodDef
Benjamin Petersond6720012009-04-18 15:31:34 +00002811bytearray_methods[] = {
2812 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2813 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2814 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2815 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002816 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2817 _Py_capitalize__doc__},
2818 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002819 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Petersondc782b52009-09-18 21:46:21 +00002820 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002821 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002822 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2823 expandtabs__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002824 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2825 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2826 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes44720832008-05-26 13:01:01 +00002827 fromhex_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002828 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2829 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002830 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2831 _Py_isalnum__doc__},
2832 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2833 _Py_isalpha__doc__},
2834 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2835 _Py_isdigit__doc__},
2836 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2837 _Py_islower__doc__},
2838 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2839 _Py_isspace__doc__},
2840 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2841 _Py_istitle__doc__},
2842 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2843 _Py_isupper__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002844 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes44720832008-05-26 13:01:01 +00002845 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2846 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002847 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2848 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2849 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2850 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2851 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2852 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2853 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2854 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002855 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002856 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2857 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2858 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2859 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrou64672132010-01-13 07:55:48 +00002860 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002861 splitlines__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002862 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes44720832008-05-26 13:01:01 +00002863 startswith__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002864 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002865 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2866 _Py_swapcase__doc__},
2867 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002868 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002869 translate__doc__},
2870 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2871 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2872 {NULL}
2873};
2874
Benjamin Petersond6720012009-04-18 15:31:34 +00002875PyDoc_STRVAR(bytearray_doc,
Christian Heimes44720832008-05-26 13:01:01 +00002876"bytearray(iterable_of_ints) -> bytearray.\n\
2877bytearray(string, encoding[, errors]) -> bytearray.\n\
2878bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
2879bytearray(memory_view) -> bytearray.\n\
2880\n\
2881Construct an mutable bytearray object from:\n\
2882 - an iterable yielding integers in range(256)\n\
2883 - a text string encoded using the specified encoding\n\
2884 - a bytes or a bytearray object\n\
2885 - any object implementing the buffer API.\n\
2886\n\
2887bytearray(int) -> bytearray.\n\
2888\n\
2889Construct a zero-initialized bytearray of the given length.");
2890
2891
Benjamin Petersond6720012009-04-18 15:31:34 +00002892static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes44720832008-05-26 13:01:01 +00002893
2894PyTypeObject PyByteArray_Type = {
2895 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2896 "bytearray",
2897 sizeof(PyByteArrayObject),
2898 0,
Benjamin Petersond6720012009-04-18 15:31:34 +00002899 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00002900 0, /* tp_print */
2901 0, /* tp_getattr */
2902 0, /* tp_setattr */
2903 0, /* tp_compare */
Benjamin Petersond6720012009-04-18 15:31:34 +00002904 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes44720832008-05-26 13:01:01 +00002905 0, /* tp_as_number */
Benjamin Petersond6720012009-04-18 15:31:34 +00002906 &bytearray_as_sequence, /* tp_as_sequence */
2907 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes44720832008-05-26 13:01:01 +00002908 0, /* tp_hash */
2909 0, /* tp_call */
Benjamin Petersond6720012009-04-18 15:31:34 +00002910 bytearray_str, /* tp_str */
Christian Heimes44720832008-05-26 13:01:01 +00002911 PyObject_GenericGetAttr, /* tp_getattro */
2912 0, /* tp_setattro */
Benjamin Petersond6720012009-04-18 15:31:34 +00002913 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes44720832008-05-26 13:01:01 +00002914 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2915 Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
Benjamin Petersond6720012009-04-18 15:31:34 +00002916 bytearray_doc, /* tp_doc */
Christian Heimes44720832008-05-26 13:01:01 +00002917 0, /* tp_traverse */
2918 0, /* tp_clear */
Benjamin Petersond6720012009-04-18 15:31:34 +00002919 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes44720832008-05-26 13:01:01 +00002920 0, /* tp_weaklistoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002921 bytearray_iter, /* tp_iter */
Christian Heimes44720832008-05-26 13:01:01 +00002922 0, /* tp_iternext */
Benjamin Petersond6720012009-04-18 15:31:34 +00002923 bytearray_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00002924 0, /* tp_members */
2925 0, /* tp_getset */
2926 0, /* tp_base */
2927 0, /* tp_dict */
2928 0, /* tp_descr_get */
2929 0, /* tp_descr_set */
2930 0, /* tp_dictoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002931 (initproc)bytearray_init, /* tp_init */
Christian Heimes44720832008-05-26 13:01:01 +00002932 PyType_GenericAlloc, /* tp_alloc */
2933 PyType_GenericNew, /* tp_new */
2934 PyObject_Del, /* tp_free */
2935};
2936
2937/*********************** Bytes Iterator ****************************/
2938
2939typedef struct {
2940 PyObject_HEAD
2941 Py_ssize_t it_index;
2942 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2943} bytesiterobject;
2944
2945static void
Benjamin Petersond6720012009-04-18 15:31:34 +00002946bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002947{
2948 _PyObject_GC_UNTRACK(it);
2949 Py_XDECREF(it->it_seq);
2950 PyObject_GC_Del(it);
2951}
2952
2953static int
Benjamin Petersond6720012009-04-18 15:31:34 +00002954bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002955{
2956 Py_VISIT(it->it_seq);
2957 return 0;
2958}
2959
2960static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002961bytearrayiter_next(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002962{
2963 PyByteArrayObject *seq;
2964 PyObject *item;
2965
2966 assert(it != NULL);
2967 seq = it->it_seq;
2968 if (seq == NULL)
2969 return NULL;
2970 assert(PyByteArray_Check(seq));
2971
2972 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2973 item = PyInt_FromLong(
2974 (unsigned char)seq->ob_bytes[it->it_index]);
2975 if (item != NULL)
2976 ++it->it_index;
2977 return item;
2978 }
2979
2980 Py_DECREF(seq);
2981 it->it_seq = NULL;
2982 return NULL;
2983}
2984
2985static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002986bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002987{
2988 Py_ssize_t len = 0;
2989 if (it->it_seq)
2990 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2991 return PyInt_FromSsize_t(len);
2992}
2993
2994PyDoc_STRVAR(length_hint_doc,
2995 "Private method returning an estimate of len(list(it)).");
2996
Benjamin Petersond6720012009-04-18 15:31:34 +00002997static PyMethodDef bytearrayiter_methods[] = {
2998 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002999 length_hint_doc},
3000 {NULL, NULL} /* sentinel */
3001};
3002
3003PyTypeObject PyByteArrayIter_Type = {
3004 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3005 "bytearray_iterator", /* tp_name */
3006 sizeof(bytesiterobject), /* tp_basicsize */
3007 0, /* tp_itemsize */
3008 /* methods */
Benjamin Petersond6720012009-04-18 15:31:34 +00003009 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00003010 0, /* tp_print */
3011 0, /* tp_getattr */
3012 0, /* tp_setattr */
3013 0, /* tp_compare */
3014 0, /* tp_repr */
3015 0, /* tp_as_number */
3016 0, /* tp_as_sequence */
3017 0, /* tp_as_mapping */
3018 0, /* tp_hash */
3019 0, /* tp_call */
3020 0, /* tp_str */
3021 PyObject_GenericGetAttr, /* tp_getattro */
3022 0, /* tp_setattro */
3023 0, /* tp_as_buffer */
3024 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3025 0, /* tp_doc */
Benjamin Petersond6720012009-04-18 15:31:34 +00003026 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes44720832008-05-26 13:01:01 +00003027 0, /* tp_clear */
3028 0, /* tp_richcompare */
3029 0, /* tp_weaklistoffset */
3030 PyObject_SelfIter, /* tp_iter */
Benjamin Petersond6720012009-04-18 15:31:34 +00003031 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3032 bytearrayiter_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00003033 0,
3034};
3035
3036static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003037bytearray_iter(PyObject *seq)
Christian Heimes44720832008-05-26 13:01:01 +00003038{
3039 bytesiterobject *it;
3040
3041 if (!PyByteArray_Check(seq)) {
3042 PyErr_BadInternalCall();
3043 return NULL;
3044 }
3045 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3046 if (it == NULL)
3047 return NULL;
3048 it->it_index = 0;
3049 Py_INCREF(seq);
3050 it->it_seq = (PyByteArrayObject *)seq;
3051 _PyObject_GC_TRACK(it);
3052 return (PyObject *)it;
3053}