blob: 5591847640d21ca0500a4540120bf15c3824b3d7 [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,
1035 "Comparsion between bytearray and string", 1))
1036 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
1114#define STRINGLIB_CMP memcmp
1115#define STRINGLIB_LEN PyByteArray_GET_SIZE
1116#define STRINGLIB_STR PyByteArray_AS_STRING
1117#define STRINGLIB_NEW PyByteArray_FromStringAndSize
1118#define STRINGLIB_EMPTY nullbytes
1119#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1120#define STRINGLIB_MUTABLE 1
Christian Heimes7d4c3172008-08-22 19:47:25 +00001121#define FROM_BYTEARRAY 1
Christian Heimes44720832008-05-26 13:01:01 +00001122
1123#include "stringlib/fastsearch.h"
1124#include "stringlib/count.h"
1125#include "stringlib/find.h"
1126#include "stringlib/partition.h"
1127#include "stringlib/ctype.h"
1128#include "stringlib/transmogrify.h"
1129
1130
1131/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1132were copied from the old char* style string object. */
1133
1134Py_LOCAL_INLINE(void)
1135_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len)
1136{
1137 if (*end > len)
1138 *end = len;
1139 else if (*end < 0)
1140 *end += len;
1141 if (*end < 0)
1142 *end = 0;
1143 if (*start < 0)
1144 *start += len;
1145 if (*start < 0)
1146 *start = 0;
1147}
1148
1149
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
1216 _adjust_indices(&start, &end, PyByteArray_GET_SIZE(self));
1217
1218 count_obj = PyInt_FromSsize_t(
1219 stringlib_count(str + start, end - start, vsub.buf, vsub.len)
1220 );
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
1327 _adjust_indices(&start, &end, len);
1328
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");
1468 goto done;
1469 }
1470 table = (const char*)vtable.buf;
Christian Heimes44720832008-05-26 13:01:01 +00001471 }
1472
1473 if (delobj != NULL) {
1474 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl6425a2f2008-12-28 11:54:53 +00001475 delobj = NULL; /* don't try to release vdel buffer on exit */
Christian Heimes44720832008-05-26 13:01:01 +00001476 goto done;
1477 }
1478 }
1479 else {
1480 vdel.buf = NULL;
1481 vdel.len = 0;
1482 }
1483
Christian Heimes44720832008-05-26 13:01:01 +00001484 inlen = PyByteArray_GET_SIZE(input_obj);
1485 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1486 if (result == NULL)
1487 goto done;
1488 output_start = output = PyByteArray_AsString(result);
1489 input = PyByteArray_AS_STRING(input_obj);
1490
Georg Brandl6425a2f2008-12-28 11:54:53 +00001491 if (vdel.len == 0 && table != NULL) {
Christian Heimes44720832008-05-26 13:01:01 +00001492 /* If no deletions are required, use faster code */
1493 for (i = inlen; --i >= 0; ) {
1494 c = Py_CHARMASK(*input++);
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001495 *output++ = table[c];
Christian Heimes44720832008-05-26 13:01:01 +00001496 }
Christian Heimes44720832008-05-26 13:01:01 +00001497 goto done;
1498 }
Georg Brandl6425a2f2008-12-28 11:54:53 +00001499
1500 if (table == NULL) {
1501 for (i = 0; i < 256; i++)
1502 trans_table[i] = Py_CHARMASK(i);
1503 } else {
1504 for (i = 0; i < 256; i++)
1505 trans_table[i] = Py_CHARMASK(table[i]);
1506 }
Christian Heimes44720832008-05-26 13:01:01 +00001507
1508 for (i = 0; i < vdel.len; i++)
1509 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1510
1511 for (i = inlen; --i >= 0; ) {
1512 c = Py_CHARMASK(*input++);
1513 if (trans_table[c] != -1)
1514 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1515 continue;
Christian Heimes44720832008-05-26 13:01:01 +00001516 }
1517 /* Fix the size of the resulting string */
1518 if (inlen > 0)
1519 PyByteArray_Resize(result, output - output_start);
1520
1521done:
Georg Brandl6425a2f2008-12-28 11:54:53 +00001522 if (tableobj != NULL)
1523 PyBuffer_Release(&vtable);
Christian Heimes44720832008-05-26 13:01:01 +00001524 if (delobj != NULL)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001525 PyBuffer_Release(&vdel);
Christian Heimes44720832008-05-26 13:01:01 +00001526 return result;
1527}
1528
1529
1530#define FORWARD 1
1531#define REVERSE -1
1532
1533/* find and count characters and substrings */
1534
1535#define findchar(target, target_len, c) \
1536 ((char *)memchr((const void *)(target), c, target_len))
1537
1538/* Don't call if length < 2 */
1539#define Py_STRING_MATCH(target, offset, pattern, length) \
1540 (target[offset] == pattern[0] && \
1541 target[offset+length-1] == pattern[length-1] && \
1542 !memcmp(target+offset+1, pattern+1, length-2) )
1543
1544
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001545/* Bytes ops must return a string, create a copy */
Christian Heimes44720832008-05-26 13:01:01 +00001546Py_LOCAL(PyByteArrayObject *)
1547return_self(PyByteArrayObject *self)
1548{
Christian Heimes44720832008-05-26 13:01:01 +00001549 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1550 PyByteArray_AS_STRING(self),
1551 PyByteArray_GET_SIZE(self));
1552}
1553
1554Py_LOCAL_INLINE(Py_ssize_t)
1555countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1556{
1557 Py_ssize_t count=0;
1558 const char *start=target;
1559 const char *end=target+target_len;
1560
1561 while ( (start=findchar(start, end-start, c)) != NULL ) {
1562 count++;
1563 if (count >= maxcount)
1564 break;
1565 start += 1;
1566 }
1567 return count;
1568}
1569
1570Py_LOCAL(Py_ssize_t)
1571findstring(const char *target, Py_ssize_t target_len,
1572 const char *pattern, Py_ssize_t pattern_len,
1573 Py_ssize_t start,
1574 Py_ssize_t end,
1575 int direction)
1576{
1577 if (start < 0) {
1578 start += target_len;
1579 if (start < 0)
1580 start = 0;
1581 }
1582 if (end > target_len) {
1583 end = target_len;
1584 } else if (end < 0) {
1585 end += target_len;
1586 if (end < 0)
1587 end = 0;
1588 }
1589
1590 /* zero-length substrings always match at the first attempt */
1591 if (pattern_len == 0)
1592 return (direction > 0) ? start : end;
1593
1594 end -= pattern_len;
1595
1596 if (direction < 0) {
1597 for (; end >= start; end--)
1598 if (Py_STRING_MATCH(target, end, pattern, pattern_len))
1599 return end;
1600 } else {
1601 for (; start <= end; start++)
1602 if (Py_STRING_MATCH(target, start, pattern, pattern_len))
1603 return start;
1604 }
1605 return -1;
1606}
1607
1608Py_LOCAL_INLINE(Py_ssize_t)
1609countstring(const char *target, Py_ssize_t target_len,
1610 const char *pattern, Py_ssize_t pattern_len,
1611 Py_ssize_t start,
1612 Py_ssize_t end,
1613 int direction, Py_ssize_t maxcount)
1614{
1615 Py_ssize_t count=0;
1616
1617 if (start < 0) {
1618 start += target_len;
1619 if (start < 0)
1620 start = 0;
1621 }
1622 if (end > target_len) {
1623 end = target_len;
1624 } else if (end < 0) {
1625 end += target_len;
1626 if (end < 0)
1627 end = 0;
1628 }
1629
1630 /* zero-length substrings match everywhere */
1631 if (pattern_len == 0 || maxcount == 0) {
1632 if (target_len+1 < maxcount)
1633 return target_len+1;
1634 return maxcount;
1635 }
1636
1637 end -= pattern_len;
1638 if (direction < 0) {
1639 for (; (end >= start); end--)
1640 if (Py_STRING_MATCH(target, end, pattern, pattern_len)) {
1641 count++;
1642 if (--maxcount <= 0) break;
1643 end -= pattern_len-1;
1644 }
1645 } else {
1646 for (; (start <= end); start++)
1647 if (Py_STRING_MATCH(target, start, pattern, pattern_len)) {
1648 count++;
1649 if (--maxcount <= 0)
1650 break;
1651 start += pattern_len-1;
1652 }
1653 }
1654 return count;
1655}
1656
1657
1658/* Algorithms for different cases of string replacement */
1659
1660/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1661Py_LOCAL(PyByteArrayObject *)
1662replace_interleave(PyByteArrayObject *self,
1663 const char *to_s, Py_ssize_t to_len,
1664 Py_ssize_t maxcount)
1665{
1666 char *self_s, *result_s;
1667 Py_ssize_t self_len, result_len;
1668 Py_ssize_t count, i, product;
1669 PyByteArrayObject *result;
1670
1671 self_len = PyByteArray_GET_SIZE(self);
1672
1673 /* 1 at the end plus 1 after every character */
1674 count = self_len+1;
1675 if (maxcount < count)
1676 count = maxcount;
1677
1678 /* Check for overflow */
1679 /* result_len = count * to_len + self_len; */
1680 product = count * to_len;
1681 if (product / to_len != count) {
1682 PyErr_SetString(PyExc_OverflowError,
1683 "replace string is too long");
1684 return NULL;
1685 }
1686 result_len = product + self_len;
1687 if (result_len < 0) {
1688 PyErr_SetString(PyExc_OverflowError,
1689 "replace string is too long");
1690 return NULL;
1691 }
1692
1693 if (! (result = (PyByteArrayObject *)
1694 PyByteArray_FromStringAndSize(NULL, result_len)) )
1695 return NULL;
1696
1697 self_s = PyByteArray_AS_STRING(self);
1698 result_s = PyByteArray_AS_STRING(result);
1699
1700 /* TODO: special case single character, which doesn't need memcpy */
1701
1702 /* Lay the first one down (guaranteed this will occur) */
1703 Py_MEMCPY(result_s, to_s, to_len);
1704 result_s += to_len;
1705 count -= 1;
1706
1707 for (i=0; i<count; i++) {
1708 *result_s++ = *self_s++;
1709 Py_MEMCPY(result_s, to_s, to_len);
1710 result_s += to_len;
1711 }
1712
1713 /* Copy the rest of the original string */
1714 Py_MEMCPY(result_s, self_s, self_len-i);
1715
1716 return result;
1717}
1718
1719/* Special case for deleting a single character */
1720/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1721Py_LOCAL(PyByteArrayObject *)
1722replace_delete_single_character(PyByteArrayObject *self,
1723 char from_c, Py_ssize_t maxcount)
1724{
1725 char *self_s, *result_s;
1726 char *start, *next, *end;
1727 Py_ssize_t self_len, result_len;
1728 Py_ssize_t count;
1729 PyByteArrayObject *result;
1730
1731 self_len = PyByteArray_GET_SIZE(self);
1732 self_s = PyByteArray_AS_STRING(self);
1733
1734 count = countchar(self_s, self_len, from_c, maxcount);
1735 if (count == 0) {
1736 return return_self(self);
1737 }
1738
1739 result_len = self_len - count; /* from_len == 1 */
1740 assert(result_len>=0);
1741
1742 if ( (result = (PyByteArrayObject *)
1743 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1744 return NULL;
1745 result_s = PyByteArray_AS_STRING(result);
1746
1747 start = self_s;
1748 end = self_s + self_len;
1749 while (count-- > 0) {
1750 next = findchar(start, end-start, from_c);
1751 if (next == NULL)
1752 break;
1753 Py_MEMCPY(result_s, start, next-start);
1754 result_s += (next-start);
1755 start = next+1;
1756 }
1757 Py_MEMCPY(result_s, start, end-start);
1758
1759 return result;
1760}
1761
1762/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1763
1764Py_LOCAL(PyByteArrayObject *)
1765replace_delete_substring(PyByteArrayObject *self,
1766 const char *from_s, Py_ssize_t from_len,
1767 Py_ssize_t maxcount)
1768{
1769 char *self_s, *result_s;
1770 char *start, *next, *end;
1771 Py_ssize_t self_len, result_len;
1772 Py_ssize_t count, offset;
1773 PyByteArrayObject *result;
1774
1775 self_len = PyByteArray_GET_SIZE(self);
1776 self_s = PyByteArray_AS_STRING(self);
1777
1778 count = countstring(self_s, self_len,
1779 from_s, from_len,
1780 0, self_len, 1,
1781 maxcount);
1782
1783 if (count == 0) {
1784 /* no matches */
1785 return return_self(self);
1786 }
1787
1788 result_len = self_len - (count * from_len);
1789 assert (result_len>=0);
1790
1791 if ( (result = (PyByteArrayObject *)
1792 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1793 return NULL;
1794
1795 result_s = PyByteArray_AS_STRING(result);
1796
1797 start = self_s;
1798 end = self_s + self_len;
1799 while (count-- > 0) {
1800 offset = findstring(start, end-start,
1801 from_s, from_len,
1802 0, end-start, FORWARD);
1803 if (offset == -1)
1804 break;
1805 next = start + offset;
1806
1807 Py_MEMCPY(result_s, start, next-start);
1808
1809 result_s += (next-start);
1810 start = next+from_len;
1811 }
1812 Py_MEMCPY(result_s, start, end-start);
1813 return result;
1814}
1815
1816/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1817Py_LOCAL(PyByteArrayObject *)
1818replace_single_character_in_place(PyByteArrayObject *self,
1819 char from_c, char to_c,
1820 Py_ssize_t maxcount)
1821{
1822 char *self_s, *result_s, *start, *end, *next;
1823 Py_ssize_t self_len;
1824 PyByteArrayObject *result;
1825
1826 /* The result string will be the same size */
1827 self_s = PyByteArray_AS_STRING(self);
1828 self_len = PyByteArray_GET_SIZE(self);
1829
1830 next = findchar(self_s, self_len, from_c);
1831
1832 if (next == NULL) {
1833 /* No matches; return the original bytes */
1834 return return_self(self);
1835 }
1836
1837 /* Need to make a new bytes */
1838 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1839 if (result == NULL)
1840 return NULL;
1841 result_s = PyByteArray_AS_STRING(result);
1842 Py_MEMCPY(result_s, self_s, self_len);
1843
1844 /* change everything in-place, starting with this one */
1845 start = result_s + (next-self_s);
1846 *start = to_c;
1847 start++;
1848 end = result_s + self_len;
1849
1850 while (--maxcount > 0) {
1851 next = findchar(start, end-start, from_c);
1852 if (next == NULL)
1853 break;
1854 *next = to_c;
1855 start = next+1;
1856 }
1857
1858 return result;
1859}
1860
1861/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1862Py_LOCAL(PyByteArrayObject *)
1863replace_substring_in_place(PyByteArrayObject *self,
1864 const char *from_s, Py_ssize_t from_len,
1865 const char *to_s, Py_ssize_t to_len,
1866 Py_ssize_t maxcount)
1867{
1868 char *result_s, *start, *end;
1869 char *self_s;
1870 Py_ssize_t self_len, offset;
1871 PyByteArrayObject *result;
1872
1873 /* The result bytes will be the same size */
1874
1875 self_s = PyByteArray_AS_STRING(self);
1876 self_len = PyByteArray_GET_SIZE(self);
1877
1878 offset = findstring(self_s, self_len,
1879 from_s, from_len,
1880 0, self_len, FORWARD);
1881 if (offset == -1) {
1882 /* No matches; return the original bytes */
1883 return return_self(self);
1884 }
1885
1886 /* Need to make a new bytes */
1887 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1888 if (result == NULL)
1889 return NULL;
1890 result_s = PyByteArray_AS_STRING(result);
1891 Py_MEMCPY(result_s, self_s, self_len);
1892
1893 /* change everything in-place, starting with this one */
1894 start = result_s + offset;
1895 Py_MEMCPY(start, to_s, from_len);
1896 start += from_len;
1897 end = result_s + self_len;
1898
1899 while ( --maxcount > 0) {
1900 offset = findstring(start, end-start,
1901 from_s, from_len,
1902 0, end-start, FORWARD);
1903 if (offset==-1)
1904 break;
1905 Py_MEMCPY(start+offset, to_s, from_len);
1906 start += offset+from_len;
1907 }
1908
1909 return result;
1910}
1911
1912/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1913Py_LOCAL(PyByteArrayObject *)
1914replace_single_character(PyByteArrayObject *self,
1915 char from_c,
1916 const char *to_s, Py_ssize_t to_len,
1917 Py_ssize_t maxcount)
1918{
1919 char *self_s, *result_s;
1920 char *start, *next, *end;
1921 Py_ssize_t self_len, result_len;
1922 Py_ssize_t count, product;
1923 PyByteArrayObject *result;
1924
1925 self_s = PyByteArray_AS_STRING(self);
1926 self_len = PyByteArray_GET_SIZE(self);
1927
1928 count = countchar(self_s, self_len, from_c, maxcount);
1929 if (count == 0) {
1930 /* no matches, return unchanged */
1931 return return_self(self);
1932 }
1933
1934 /* use the difference between current and new, hence the "-1" */
1935 /* result_len = self_len + count * (to_len-1) */
1936 product = count * (to_len-1);
1937 if (product / (to_len-1) != count) {
1938 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1939 return NULL;
1940 }
1941 result_len = self_len + product;
1942 if (result_len < 0) {
1943 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1944 return NULL;
1945 }
1946
1947 if ( (result = (PyByteArrayObject *)
1948 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1949 return NULL;
1950 result_s = PyByteArray_AS_STRING(result);
1951
1952 start = self_s;
1953 end = self_s + self_len;
1954 while (count-- > 0) {
1955 next = findchar(start, end-start, from_c);
1956 if (next == NULL)
1957 break;
1958
1959 if (next == start) {
1960 /* replace with the 'to' */
1961 Py_MEMCPY(result_s, to_s, to_len);
1962 result_s += to_len;
1963 start += 1;
1964 } else {
1965 /* copy the unchanged old then the 'to' */
1966 Py_MEMCPY(result_s, start, next-start);
1967 result_s += (next-start);
1968 Py_MEMCPY(result_s, to_s, to_len);
1969 result_s += to_len;
1970 start = next+1;
1971 }
1972 }
1973 /* Copy the remainder of the remaining bytes */
1974 Py_MEMCPY(result_s, start, end-start);
1975
1976 return result;
1977}
1978
1979/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1980Py_LOCAL(PyByteArrayObject *)
1981replace_substring(PyByteArrayObject *self,
1982 const char *from_s, Py_ssize_t from_len,
1983 const char *to_s, Py_ssize_t to_len,
1984 Py_ssize_t maxcount)
1985{
1986 char *self_s, *result_s;
1987 char *start, *next, *end;
1988 Py_ssize_t self_len, result_len;
1989 Py_ssize_t count, offset, product;
1990 PyByteArrayObject *result;
1991
1992 self_s = PyByteArray_AS_STRING(self);
1993 self_len = PyByteArray_GET_SIZE(self);
1994
1995 count = countstring(self_s, self_len,
1996 from_s, from_len,
1997 0, self_len, FORWARD, maxcount);
1998 if (count == 0) {
1999 /* no matches, return unchanged */
2000 return return_self(self);
2001 }
2002
2003 /* Check for overflow */
2004 /* result_len = self_len + count * (to_len-from_len) */
2005 product = count * (to_len-from_len);
2006 if (product / (to_len-from_len) != count) {
2007 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
2008 return NULL;
2009 }
2010 result_len = self_len + product;
2011 if (result_len < 0) {
2012 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
2013 return NULL;
2014 }
2015
2016 if ( (result = (PyByteArrayObject *)
2017 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
2018 return NULL;
2019 result_s = PyByteArray_AS_STRING(result);
2020
2021 start = self_s;
2022 end = self_s + self_len;
2023 while (count-- > 0) {
2024 offset = findstring(start, end-start,
2025 from_s, from_len,
2026 0, end-start, FORWARD);
2027 if (offset == -1)
2028 break;
2029 next = start+offset;
2030 if (next == start) {
2031 /* replace with the 'to' */
2032 Py_MEMCPY(result_s, to_s, to_len);
2033 result_s += to_len;
2034 start += from_len;
2035 } else {
2036 /* copy the unchanged old then the 'to' */
2037 Py_MEMCPY(result_s, start, next-start);
2038 result_s += (next-start);
2039 Py_MEMCPY(result_s, to_s, to_len);
2040 result_s += to_len;
2041 start = next+from_len;
2042 }
2043 }
2044 /* Copy the remainder of the remaining bytes */
2045 Py_MEMCPY(result_s, start, end-start);
2046
2047 return result;
2048}
2049
2050
2051Py_LOCAL(PyByteArrayObject *)
2052replace(PyByteArrayObject *self,
2053 const char *from_s, Py_ssize_t from_len,
2054 const char *to_s, Py_ssize_t to_len,
2055 Py_ssize_t maxcount)
2056{
2057 if (maxcount < 0) {
2058 maxcount = PY_SSIZE_T_MAX;
2059 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
2060 /* nothing to do; return the original bytes */
2061 return return_self(self);
2062 }
2063
2064 if (maxcount == 0 ||
2065 (from_len == 0 && to_len == 0)) {
2066 /* nothing to do; return the original bytes */
2067 return return_self(self);
2068 }
2069
2070 /* Handle zero-length special cases */
2071
2072 if (from_len == 0) {
2073 /* insert the 'to' bytes everywhere. */
2074 /* >>> "Python".replace("", ".") */
2075 /* '.P.y.t.h.o.n.' */
2076 return replace_interleave(self, to_s, to_len, maxcount);
2077 }
2078
2079 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2080 /* point for an empty self bytes to generate a non-empty bytes */
2081 /* Special case so the remaining code always gets a non-empty bytes */
2082 if (PyByteArray_GET_SIZE(self) == 0) {
2083 return return_self(self);
2084 }
2085
2086 if (to_len == 0) {
2087 /* delete all occurances of 'from' bytes */
2088 if (from_len == 1) {
2089 return replace_delete_single_character(
2090 self, from_s[0], maxcount);
2091 } else {
2092 return replace_delete_substring(self, from_s, from_len, maxcount);
2093 }
2094 }
2095
2096 /* Handle special case where both bytes have the same length */
2097
2098 if (from_len == to_len) {
2099 if (from_len == 1) {
2100 return replace_single_character_in_place(
2101 self,
2102 from_s[0],
2103 to_s[0],
2104 maxcount);
2105 } else {
2106 return replace_substring_in_place(
2107 self, from_s, from_len, to_s, to_len, maxcount);
2108 }
2109 }
2110
2111 /* Otherwise use the more generic algorithms */
2112 if (from_len == 1) {
2113 return replace_single_character(self, from_s[0],
2114 to_s, to_len, maxcount);
2115 } else {
2116 /* len('from')>=2, len('to')>=1 */
2117 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2118 }
2119}
2120
2121
2122PyDoc_STRVAR(replace__doc__,
2123"B.replace(old, new[, count]) -> bytes\n\
2124\n\
2125Return a copy of B with all occurrences of subsection\n\
2126old replaced by new. If the optional argument count is\n\
2127given, only the first count occurrences are replaced.");
2128
2129static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002130bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002131{
2132 Py_ssize_t count = -1;
2133 PyObject *from, *to, *res;
2134 Py_buffer vfrom, vto;
2135
2136 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2137 return NULL;
2138
2139 if (_getbuffer(from, &vfrom) < 0)
2140 return NULL;
2141 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002142 PyBuffer_Release(&vfrom);
Christian Heimes44720832008-05-26 13:01:01 +00002143 return NULL;
2144 }
2145
2146 res = (PyObject *)replace((PyByteArrayObject *) self,
2147 vfrom.buf, vfrom.len,
2148 vto.buf, vto.len, count);
2149
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002150 PyBuffer_Release(&vfrom);
2151 PyBuffer_Release(&vto);
Christian Heimes44720832008-05-26 13:01:01 +00002152 return res;
2153}
2154
2155
2156/* Overallocate the initial list to reduce the number of reallocs for small
2157 split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three
2158 resizes, to sizes 4, 8, then 16. Most observed string splits are for human
2159 text (roughly 11 words per line) and field delimited data (usually 1-10
2160 fields). For large strings the split algorithms are bandwidth limited
2161 so increasing the preallocation likely will not improve things.*/
2162
2163#define MAX_PREALLOC 12
2164
2165/* 5 splits gives 6 elements */
2166#define PREALLOC_SIZE(maxsplit) \
2167 (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
2168
2169#define SPLIT_APPEND(data, left, right) \
2170 str = PyByteArray_FromStringAndSize((data) + (left), \
2171 (right) - (left)); \
2172 if (str == NULL) \
2173 goto onError; \
2174 if (PyList_Append(list, str)) { \
2175 Py_DECREF(str); \
2176 goto onError; \
2177 } \
2178 else \
2179 Py_DECREF(str);
2180
2181#define SPLIT_ADD(data, left, right) { \
2182 str = PyByteArray_FromStringAndSize((data) + (left), \
2183 (right) - (left)); \
2184 if (str == NULL) \
2185 goto onError; \
2186 if (count < MAX_PREALLOC) { \
2187 PyList_SET_ITEM(list, count, str); \
2188 } else { \
2189 if (PyList_Append(list, str)) { \
2190 Py_DECREF(str); \
2191 goto onError; \
2192 } \
2193 else \
2194 Py_DECREF(str); \
2195 } \
2196 count++; }
2197
2198/* Always force the list to the expected size. */
2199#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
2200
2201
2202Py_LOCAL_INLINE(PyObject *)
2203split_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
2204{
2205 register Py_ssize_t i, j, count = 0;
2206 PyObject *str;
2207 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2208
2209 if (list == NULL)
2210 return NULL;
2211
2212 i = j = 0;
2213 while ((j < len) && (maxcount-- > 0)) {
2214 for(; j < len; j++) {
2215 /* I found that using memchr makes no difference */
2216 if (s[j] == ch) {
2217 SPLIT_ADD(s, i, j);
2218 i = j = j + 1;
2219 break;
2220 }
2221 }
2222 }
2223 if (i <= len) {
2224 SPLIT_ADD(s, i, len);
2225 }
2226 FIX_PREALLOC_SIZE(list);
2227 return list;
2228
2229 onError:
2230 Py_DECREF(list);
2231 return NULL;
2232}
2233
2234
2235Py_LOCAL_INLINE(PyObject *)
2236split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
2237{
2238 register Py_ssize_t i, j, count = 0;
2239 PyObject *str;
2240 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2241
2242 if (list == NULL)
2243 return NULL;
2244
2245 for (i = j = 0; i < len; ) {
2246 /* find a token */
Eric Smithcac7af62009-04-27 19:04:37 +00002247 while (i < len && Py_ISSPACE(s[i]))
Christian Heimes44720832008-05-26 13:01:01 +00002248 i++;
2249 j = i;
Eric Smithcac7af62009-04-27 19:04:37 +00002250 while (i < len && !Py_ISSPACE(s[i]))
Christian Heimes44720832008-05-26 13:01:01 +00002251 i++;
2252 if (j < i) {
2253 if (maxcount-- <= 0)
2254 break;
2255 SPLIT_ADD(s, j, i);
Eric Smithcac7af62009-04-27 19:04:37 +00002256 while (i < len && Py_ISSPACE(s[i]))
Christian Heimes44720832008-05-26 13:01:01 +00002257 i++;
2258 j = i;
2259 }
2260 }
2261 if (j < len) {
2262 SPLIT_ADD(s, j, len);
2263 }
2264 FIX_PREALLOC_SIZE(list);
2265 return list;
2266
2267 onError:
2268 Py_DECREF(list);
2269 return NULL;
2270}
2271
2272PyDoc_STRVAR(split__doc__,
2273"B.split([sep[, maxsplit]]) -> list of bytearray\n\
2274\n\
2275Return a list of the sections in B, using sep as the delimiter.\n\
2276If sep is not given, B is split on ASCII whitespace characters\n\
2277(space, tab, return, newline, formfeed, vertical tab).\n\
2278If maxsplit is given, at most maxsplit splits are done.");
2279
2280static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002281bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002282{
2283 Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
2284 Py_ssize_t maxsplit = -1, count = 0;
2285 const char *s = PyByteArray_AS_STRING(self), *sub;
2286 PyObject *list, *str, *subobj = Py_None;
2287 Py_buffer vsub;
2288#ifdef USE_FAST
2289 Py_ssize_t pos;
2290#endif
2291
2292 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2293 return NULL;
2294 if (maxsplit < 0)
2295 maxsplit = PY_SSIZE_T_MAX;
2296
2297 if (subobj == Py_None)
2298 return split_whitespace(s, len, maxsplit);
2299
2300 if (_getbuffer(subobj, &vsub) < 0)
2301 return NULL;
2302 sub = vsub.buf;
2303 n = vsub.len;
2304
2305 if (n == 0) {
2306 PyErr_SetString(PyExc_ValueError, "empty separator");
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002307 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002308 return NULL;
2309 }
Amaury Forgeot d'Arc313bda12008-08-17 21:05:18 +00002310 if (n == 1) {
2311 list = split_char(s, len, sub[0], maxsplit);
2312 PyBuffer_Release(&vsub);
2313 return list;
2314 }
Christian Heimes44720832008-05-26 13:01:01 +00002315
2316 list = PyList_New(PREALLOC_SIZE(maxsplit));
2317 if (list == NULL) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002318 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002319 return NULL;
2320 }
2321
2322#ifdef USE_FAST
2323 i = j = 0;
2324 while (maxsplit-- > 0) {
2325 pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH);
2326 if (pos < 0)
2327 break;
2328 j = i+pos;
2329 SPLIT_ADD(s, i, j);
2330 i = j + n;
2331 }
2332#else
2333 i = j = 0;
2334 while ((j+n <= len) && (maxsplit-- > 0)) {
2335 for (; j+n <= len; j++) {
2336 if (Py_STRING_MATCH(s, j, sub, n)) {
2337 SPLIT_ADD(s, i, j);
2338 i = j = j + n;
2339 break;
2340 }
2341 }
2342 }
2343#endif
2344 SPLIT_ADD(s, i, len);
2345 FIX_PREALLOC_SIZE(list);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002346 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002347 return list;
2348
2349 onError:
2350 Py_DECREF(list);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002351 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002352 return NULL;
2353}
2354
2355/* stringlib's partition shares nullbytes in some cases.
2356 undo this, we don't want the nullbytes to be shared. */
2357static PyObject *
2358make_nullbytes_unique(PyObject *result)
2359{
2360 if (result != NULL) {
2361 int i;
2362 assert(PyTuple_Check(result));
2363 assert(PyTuple_GET_SIZE(result) == 3);
2364 for (i = 0; i < 3; i++) {
2365 if (PyTuple_GET_ITEM(result, i) == (PyObject *)nullbytes) {
2366 PyObject *new = PyByteArray_FromStringAndSize(NULL, 0);
2367 if (new == NULL) {
2368 Py_DECREF(result);
2369 result = NULL;
2370 break;
2371 }
2372 Py_DECREF(nullbytes);
2373 PyTuple_SET_ITEM(result, i, new);
2374 }
2375 }
2376 }
2377 return result;
2378}
2379
2380PyDoc_STRVAR(partition__doc__,
2381"B.partition(sep) -> (head, sep, tail)\n\
2382\n\
2383Searches for the separator sep in B, and returns the part before it,\n\
2384the separator itself, and the part after it. If the separator is not\n\
2385found, returns B and two empty bytearray objects.");
2386
2387static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002388bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002389{
2390 PyObject *bytesep, *result;
2391
2392 bytesep = PyByteArray_FromObject(sep_obj);
2393 if (! bytesep)
2394 return NULL;
2395
2396 result = stringlib_partition(
2397 (PyObject*) self,
2398 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2399 bytesep,
2400 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2401 );
2402
2403 Py_DECREF(bytesep);
2404 return make_nullbytes_unique(result);
2405}
2406
2407PyDoc_STRVAR(rpartition__doc__,
2408"B.rpartition(sep) -> (tail, sep, head)\n\
2409\n\
2410Searches for the separator sep in B, starting at the end of B,\n\
2411and returns the part before it, the separator itself, and the\n\
2412part after it. If the separator is not found, returns two empty\n\
2413bytearray objects and B.");
2414
2415static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002416bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002417{
2418 PyObject *bytesep, *result;
2419
2420 bytesep = PyByteArray_FromObject(sep_obj);
2421 if (! bytesep)
2422 return NULL;
2423
2424 result = stringlib_rpartition(
2425 (PyObject*) self,
2426 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2427 bytesep,
2428 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2429 );
2430
2431 Py_DECREF(bytesep);
2432 return make_nullbytes_unique(result);
2433}
2434
2435Py_LOCAL_INLINE(PyObject *)
2436rsplit_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
2437{
2438 register Py_ssize_t i, j, count=0;
2439 PyObject *str;
2440 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2441
2442 if (list == NULL)
2443 return NULL;
2444
2445 i = j = len - 1;
2446 while ((i >= 0) && (maxcount-- > 0)) {
2447 for (; i >= 0; i--) {
2448 if (s[i] == ch) {
2449 SPLIT_ADD(s, i + 1, j + 1);
2450 j = i = i - 1;
2451 break;
2452 }
2453 }
2454 }
2455 if (j >= -1) {
2456 SPLIT_ADD(s, 0, j + 1);
2457 }
2458 FIX_PREALLOC_SIZE(list);
2459 if (PyList_Reverse(list) < 0)
2460 goto onError;
2461
2462 return list;
2463
2464 onError:
2465 Py_DECREF(list);
2466 return NULL;
2467}
2468
2469Py_LOCAL_INLINE(PyObject *)
2470rsplit_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
2471{
2472 register Py_ssize_t i, j, count = 0;
2473 PyObject *str;
2474 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2475
2476 if (list == NULL)
2477 return NULL;
2478
2479 for (i = j = len - 1; i >= 0; ) {
2480 /* find a token */
Eric Smithcac7af62009-04-27 19:04:37 +00002481 while (i >= 0 && Py_ISSPACE(s[i]))
Christian Heimes44720832008-05-26 13:01:01 +00002482 i--;
2483 j = i;
Eric Smithcac7af62009-04-27 19:04:37 +00002484 while (i >= 0 && !Py_ISSPACE(s[i]))
Christian Heimes44720832008-05-26 13:01:01 +00002485 i--;
2486 if (j > i) {
2487 if (maxcount-- <= 0)
2488 break;
2489 SPLIT_ADD(s, i + 1, j + 1);
Eric Smithcac7af62009-04-27 19:04:37 +00002490 while (i >= 0 && Py_ISSPACE(s[i]))
Christian Heimes44720832008-05-26 13:01:01 +00002491 i--;
2492 j = i;
2493 }
2494 }
2495 if (j >= 0) {
2496 SPLIT_ADD(s, 0, j + 1);
2497 }
2498 FIX_PREALLOC_SIZE(list);
2499 if (PyList_Reverse(list) < 0)
2500 goto onError;
2501
2502 return list;
2503
2504 onError:
2505 Py_DECREF(list);
2506 return NULL;
2507}
2508
2509PyDoc_STRVAR(rsplit__doc__,
2510"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2511\n\
2512Return a list of the sections in B, using sep as the delimiter,\n\
2513starting at the end of B and working to the front.\n\
2514If sep is not given, B is split on ASCII whitespace characters\n\
2515(space, tab, return, newline, formfeed, vertical tab).\n\
2516If maxsplit is given, at most maxsplit splits are done.");
2517
2518static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002519bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002520{
2521 Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
2522 Py_ssize_t maxsplit = -1, count = 0;
2523 const char *s = PyByteArray_AS_STRING(self), *sub;
2524 PyObject *list, *str, *subobj = Py_None;
2525 Py_buffer vsub;
2526
2527 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2528 return NULL;
2529 if (maxsplit < 0)
2530 maxsplit = PY_SSIZE_T_MAX;
2531
2532 if (subobj == Py_None)
2533 return rsplit_whitespace(s, len, maxsplit);
2534
2535 if (_getbuffer(subobj, &vsub) < 0)
2536 return NULL;
2537 sub = vsub.buf;
2538 n = vsub.len;
2539
2540 if (n == 0) {
2541 PyErr_SetString(PyExc_ValueError, "empty separator");
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002542 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002543 return NULL;
2544 }
Amaury Forgeot d'Arc313bda12008-08-17 21:05:18 +00002545 else if (n == 1) {
2546 list = rsplit_char(s, len, sub[0], maxsplit);
2547 PyBuffer_Release(&vsub);
2548 return list;
2549 }
Christian Heimes44720832008-05-26 13:01:01 +00002550
2551 list = PyList_New(PREALLOC_SIZE(maxsplit));
2552 if (list == NULL) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002553 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002554 return NULL;
2555 }
2556
2557 j = len;
2558 i = j - n;
2559
2560 while ( (i >= 0) && (maxsplit-- > 0) ) {
2561 for (; i>=0; i--) {
2562 if (Py_STRING_MATCH(s, i, sub, n)) {
2563 SPLIT_ADD(s, i + n, j);
2564 j = i;
2565 i -= n;
2566 break;
2567 }
2568 }
2569 }
2570 SPLIT_ADD(s, 0, j);
2571 FIX_PREALLOC_SIZE(list);
2572 if (PyList_Reverse(list) < 0)
2573 goto onError;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002574 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002575 return list;
2576
2577onError:
2578 Py_DECREF(list);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002579 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002580 return NULL;
2581}
2582
2583PyDoc_STRVAR(reverse__doc__,
2584"B.reverse() -> None\n\
2585\n\
2586Reverse the order of the values in B in place.");
2587static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002588bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes44720832008-05-26 13:01:01 +00002589{
2590 char swap, *head, *tail;
2591 Py_ssize_t i, j, n = Py_SIZE(self);
2592
2593 j = n / 2;
2594 head = self->ob_bytes;
2595 tail = head + n - 1;
2596 for (i = 0; i < j; i++) {
2597 swap = *head;
2598 *head++ = *tail;
2599 *tail-- = swap;
2600 }
2601
2602 Py_RETURN_NONE;
2603}
2604
2605PyDoc_STRVAR(insert__doc__,
2606"B.insert(index, int) -> None\n\
2607\n\
2608Insert a single item into the bytearray before the given index.");
2609static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002610bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002611{
Georg Brandl3e483f62008-07-16 22:57:41 +00002612 PyObject *value;
2613 int ival;
Christian Heimes44720832008-05-26 13:01:01 +00002614 Py_ssize_t where, n = Py_SIZE(self);
2615
Georg Brandl3e483f62008-07-16 22:57:41 +00002616 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes44720832008-05-26 13:01:01 +00002617 return NULL;
2618
2619 if (n == PY_SSIZE_T_MAX) {
2620 PyErr_SetString(PyExc_OverflowError,
2621 "cannot add more objects to bytes");
2622 return NULL;
2623 }
Georg Brandl3e483f62008-07-16 22:57:41 +00002624 if (!_getbytevalue(value, &ival))
Christian Heimes44720832008-05-26 13:01:01 +00002625 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002626 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2627 return NULL;
2628
2629 if (where < 0) {
2630 where += n;
2631 if (where < 0)
2632 where = 0;
2633 }
2634 if (where > n)
2635 where = n;
2636 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl3e483f62008-07-16 22:57:41 +00002637 self->ob_bytes[where] = ival;
Christian Heimes44720832008-05-26 13:01:01 +00002638
2639 Py_RETURN_NONE;
2640}
2641
2642PyDoc_STRVAR(append__doc__,
2643"B.append(int) -> None\n\
2644\n\
2645Append a single item to the end of B.");
2646static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002647bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002648{
2649 int value;
2650 Py_ssize_t n = Py_SIZE(self);
2651
2652 if (! _getbytevalue(arg, &value))
2653 return NULL;
2654 if (n == PY_SSIZE_T_MAX) {
2655 PyErr_SetString(PyExc_OverflowError,
2656 "cannot add more objects to bytes");
2657 return NULL;
2658 }
2659 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2660 return NULL;
2661
2662 self->ob_bytes[n] = value;
2663
2664 Py_RETURN_NONE;
2665}
2666
2667PyDoc_STRVAR(extend__doc__,
2668"B.extend(iterable int) -> None\n\
2669\n\
2670Append all the elements from the iterator or sequence to the\n\
2671end of B.");
2672static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002673bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002674{
Benjamin Petersond6720012009-04-18 15:31:34 +00002675 PyObject *it, *item, *bytearray_obj;
Christian Heimes44720832008-05-26 13:01:01 +00002676 Py_ssize_t buf_size = 0, len = 0;
2677 int value;
2678 char *buf;
2679
Benjamin Petersond6720012009-04-18 15:31:34 +00002680 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes44720832008-05-26 13:01:01 +00002681 if (PyObject_CheckBuffer(arg)) {
Benjamin Petersond6720012009-04-18 15:31:34 +00002682 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002683 return NULL;
2684
2685 Py_RETURN_NONE;
2686 }
2687
2688 it = PyObject_GetIter(arg);
2689 if (it == NULL)
2690 return NULL;
2691
2692 /* Try to determine the length of the argument. 32 is abitrary. */
2693 buf_size = _PyObject_LengthHint(arg, 32);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002694 if (buf_size == -1) {
2695 Py_DECREF(it);
2696 return NULL;
2697 }
Christian Heimes44720832008-05-26 13:01:01 +00002698
Benjamin Petersond6720012009-04-18 15:31:34 +00002699 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2700 if (bytearray_obj == NULL)
Christian Heimes44720832008-05-26 13:01:01 +00002701 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002702 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002703
2704 while ((item = PyIter_Next(it)) != NULL) {
2705 if (! _getbytevalue(item, &value)) {
2706 Py_DECREF(item);
2707 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002708 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002709 return NULL;
2710 }
2711 buf[len++] = value;
2712 Py_DECREF(item);
2713
2714 if (len >= buf_size) {
2715 buf_size = len + (len >> 1) + 1;
Benjamin Petersond6720012009-04-18 15:31:34 +00002716 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00002717 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002718 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002719 return NULL;
2720 }
2721 /* Recompute the `buf' pointer, since the resizing operation may
2722 have invalidated it. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002723 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002724 }
2725 }
2726 Py_DECREF(it);
2727
2728 /* Resize down to exact size. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002729 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2730 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002731 return NULL;
2732 }
2733
Benjamin Petersond6720012009-04-18 15:31:34 +00002734 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002735 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002736 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002737
2738 Py_RETURN_NONE;
2739}
2740
2741PyDoc_STRVAR(pop__doc__,
2742"B.pop([index]) -> int\n\
2743\n\
2744Remove and return a single item from B. If no index\n\
Andrew M. Kuchlingd8972642008-06-21 13:29:12 +00002745argument is given, will pop the last value.");
Christian Heimes44720832008-05-26 13:01:01 +00002746static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002747bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002748{
2749 int value;
2750 Py_ssize_t where = -1, n = Py_SIZE(self);
2751
2752 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2753 return NULL;
2754
2755 if (n == 0) {
2756 PyErr_SetString(PyExc_OverflowError,
2757 "cannot pop an empty bytes");
2758 return NULL;
2759 }
2760 if (where < 0)
2761 where += Py_SIZE(self);
2762 if (where < 0 || where >= Py_SIZE(self)) {
2763 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2764 return NULL;
2765 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002766 if (!_canresize(self))
2767 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002768
2769 value = self->ob_bytes[where];
2770 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2771 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2772 return NULL;
2773
2774 return PyInt_FromLong(value);
2775}
2776
2777PyDoc_STRVAR(remove__doc__,
2778"B.remove(int) -> None\n\
2779\n\
2780Remove the first occurance of a value in B.");
2781static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002782bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002783{
2784 int value;
2785 Py_ssize_t where, n = Py_SIZE(self);
2786
2787 if (! _getbytevalue(arg, &value))
2788 return NULL;
2789
2790 for (where = 0; where < n; where++) {
2791 if (self->ob_bytes[where] == value)
2792 break;
2793 }
2794 if (where == n) {
2795 PyErr_SetString(PyExc_ValueError, "value not found in bytes");
2796 return NULL;
2797 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002798 if (!_canresize(self))
2799 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002800
2801 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2802 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2803 return NULL;
2804
2805 Py_RETURN_NONE;
2806}
2807
2808/* XXX These two helpers could be optimized if argsize == 1 */
2809
2810static Py_ssize_t
2811lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2812 void *argptr, Py_ssize_t argsize)
2813{
2814 Py_ssize_t i = 0;
2815 while (i < mysize && memchr(argptr, myptr[i], argsize))
2816 i++;
2817 return i;
2818}
2819
2820static Py_ssize_t
2821rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2822 void *argptr, Py_ssize_t argsize)
2823{
2824 Py_ssize_t i = mysize - 1;
2825 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2826 i--;
2827 return i + 1;
2828}
2829
2830PyDoc_STRVAR(strip__doc__,
2831"B.strip([bytes]) -> bytearray\n\
2832\n\
2833Strip leading and trailing bytes contained in the argument.\n\
2834If the argument is omitted, strip ASCII whitespace.");
2835static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002836bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002837{
2838 Py_ssize_t left, right, mysize, argsize;
2839 void *myptr, *argptr;
2840 PyObject *arg = Py_None;
2841 Py_buffer varg;
2842 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2843 return NULL;
2844 if (arg == Py_None) {
2845 argptr = "\t\n\r\f\v ";
2846 argsize = 6;
2847 }
2848 else {
2849 if (_getbuffer(arg, &varg) < 0)
2850 return NULL;
2851 argptr = varg.buf;
2852 argsize = varg.len;
2853 }
2854 myptr = self->ob_bytes;
2855 mysize = Py_SIZE(self);
2856 left = lstrip_helper(myptr, mysize, argptr, argsize);
2857 if (left == mysize)
2858 right = left;
2859 else
2860 right = rstrip_helper(myptr, mysize, argptr, argsize);
2861 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002862 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002863 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2864}
2865
2866PyDoc_STRVAR(lstrip__doc__,
2867"B.lstrip([bytes]) -> bytearray\n\
2868\n\
2869Strip leading bytes contained in the argument.\n\
2870If the argument is omitted, strip leading ASCII whitespace.");
2871static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002872bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002873{
2874 Py_ssize_t left, right, mysize, argsize;
2875 void *myptr, *argptr;
2876 PyObject *arg = Py_None;
2877 Py_buffer varg;
2878 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2879 return NULL;
2880 if (arg == Py_None) {
2881 argptr = "\t\n\r\f\v ";
2882 argsize = 6;
2883 }
2884 else {
2885 if (_getbuffer(arg, &varg) < 0)
2886 return NULL;
2887 argptr = varg.buf;
2888 argsize = varg.len;
2889 }
2890 myptr = self->ob_bytes;
2891 mysize = Py_SIZE(self);
2892 left = lstrip_helper(myptr, mysize, argptr, argsize);
2893 right = mysize;
2894 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002895 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002896 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2897}
2898
2899PyDoc_STRVAR(rstrip__doc__,
2900"B.rstrip([bytes]) -> bytearray\n\
2901\n\
2902Strip trailing bytes contained in the argument.\n\
2903If the argument is omitted, strip trailing ASCII whitespace.");
2904static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002905bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002906{
2907 Py_ssize_t left, right, mysize, argsize;
2908 void *myptr, *argptr;
2909 PyObject *arg = Py_None;
2910 Py_buffer varg;
2911 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2912 return NULL;
2913 if (arg == Py_None) {
2914 argptr = "\t\n\r\f\v ";
2915 argsize = 6;
2916 }
2917 else {
2918 if (_getbuffer(arg, &varg) < 0)
2919 return NULL;
2920 argptr = varg.buf;
2921 argsize = varg.len;
2922 }
2923 myptr = self->ob_bytes;
2924 mysize = Py_SIZE(self);
2925 left = 0;
2926 right = rstrip_helper(myptr, mysize, argptr, argsize);
2927 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002928 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002929 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2930}
2931
2932PyDoc_STRVAR(decode_doc,
2933"B.decode([encoding[, errors]]) -> unicode object.\n\
2934\n\
2935Decodes B using the codec registered for encoding. encoding defaults\n\
2936to the default encoding. errors may be given to set a different error\n\
2937handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2938a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2939as well as any other name registered with codecs.register_error that is\n\
2940able to handle UnicodeDecodeErrors.");
2941
2942static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002943bytearray_decode(PyObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002944{
2945 const char *encoding = NULL;
2946 const char *errors = NULL;
2947
2948 if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
2949 return NULL;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002950 if (encoding == NULL) {
2951#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002952 encoding = PyUnicode_GetDefaultEncoding();
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002953#else
2954 PyErr_SetString(PyExc_ValueError, "no encoding specified");
2955 return NULL;
2956#endif
2957 }
Christian Heimes44720832008-05-26 13:01:01 +00002958 return PyCodec_Decode(self, encoding, errors);
2959}
2960
2961PyDoc_STRVAR(alloc_doc,
2962"B.__alloc__() -> int\n\
2963\n\
2964Returns the number of bytes actually allocated.");
2965
2966static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002967bytearray_alloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002968{
2969 return PyInt_FromSsize_t(self->ob_alloc);
2970}
2971
2972PyDoc_STRVAR(join_doc,
2973"B.join(iterable_of_bytes) -> bytes\n\
2974\n\
2975Concatenates any number of bytearray objects, with B in between each pair.");
2976
2977static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002978bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002979{
2980 PyObject *seq;
2981 Py_ssize_t mysize = Py_SIZE(self);
2982 Py_ssize_t i;
2983 Py_ssize_t n;
2984 PyObject **items;
2985 Py_ssize_t totalsize = 0;
2986 PyObject *result;
2987 char *dest;
2988
2989 seq = PySequence_Fast(it, "can only join an iterable");
2990 if (seq == NULL)
2991 return NULL;
2992 n = PySequence_Fast_GET_SIZE(seq);
2993 items = PySequence_Fast_ITEMS(seq);
2994
2995 /* Compute the total size, and check that they are all bytes */
2996 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2997 for (i = 0; i < n; i++) {
2998 PyObject *obj = items[i];
2999 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
3000 PyErr_Format(PyExc_TypeError,
3001 "can only join an iterable of bytes "
3002 "(item %ld has type '%.100s')",
3003 /* XXX %ld isn't right on Win64 */
3004 (long)i, Py_TYPE(obj)->tp_name);
3005 goto error;
3006 }
3007 if (i > 0)
3008 totalsize += mysize;
3009 totalsize += Py_SIZE(obj);
3010 if (totalsize < 0) {
3011 PyErr_NoMemory();
3012 goto error;
3013 }
3014 }
3015
3016 /* Allocate the result, and copy the bytes */
3017 result = PyByteArray_FromStringAndSize(NULL, totalsize);
3018 if (result == NULL)
3019 goto error;
3020 dest = PyByteArray_AS_STRING(result);
3021 for (i = 0; i < n; i++) {
3022 PyObject *obj = items[i];
3023 Py_ssize_t size = Py_SIZE(obj);
3024 char *buf;
3025 if (PyByteArray_Check(obj))
3026 buf = PyByteArray_AS_STRING(obj);
3027 else
3028 buf = PyBytes_AS_STRING(obj);
3029 if (i) {
3030 memcpy(dest, self->ob_bytes, mysize);
3031 dest += mysize;
3032 }
3033 memcpy(dest, buf, size);
3034 dest += size;
3035 }
3036
3037 /* Done */
3038 Py_DECREF(seq);
3039 return result;
3040
3041 /* Error handling */
3042 error:
3043 Py_DECREF(seq);
3044 return NULL;
3045}
3046
3047PyDoc_STRVAR(fromhex_doc,
3048"bytearray.fromhex(string) -> bytearray\n\
3049\n\
3050Create a bytearray object from a string of hexadecimal numbers.\n\
3051Spaces between two numbers are accepted.\n\
3052Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
3053
3054static int
Benjamin Peterson78821dd2009-01-25 17:15:10 +00003055hex_digit_to_int(char c)
Christian Heimes44720832008-05-26 13:01:01 +00003056{
Eric Smithcac7af62009-04-27 19:04:37 +00003057 if (Py_ISDIGIT(c))
Christian Heimes44720832008-05-26 13:01:01 +00003058 return c - '0';
3059 else {
Eric Smithcac7af62009-04-27 19:04:37 +00003060 if (Py_ISUPPER(c))
3061 c = Py_TOLOWER(c);
Christian Heimes44720832008-05-26 13:01:01 +00003062 if (c >= 'a' && c <= 'f')
3063 return c - 'a' + 10;
3064 }
3065 return -1;
3066}
3067
3068static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003069bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00003070{
Benjamin Peterson78821dd2009-01-25 17:15:10 +00003071 PyObject *newbytes;
Christian Heimes44720832008-05-26 13:01:01 +00003072 char *buf;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00003073 char *hex;
Christian Heimes44720832008-05-26 13:01:01 +00003074 Py_ssize_t hexlen, byteslen, i, j;
3075 int top, bot;
3076
Benjamin Peterson78821dd2009-01-25 17:15:10 +00003077 if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
Christian Heimes44720832008-05-26 13:01:01 +00003078 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00003079 byteslen = hexlen/2; /* This overestimates if there are spaces */
3080 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
3081 if (!newbytes)
3082 return NULL;
3083 buf = PyByteArray_AS_STRING(newbytes);
3084 for (i = j = 0; i < hexlen; i += 2) {
3085 /* skip over spaces in the input */
3086 while (hex[i] == ' ')
3087 i++;
3088 if (i >= hexlen)
3089 break;
3090 top = hex_digit_to_int(hex[i]);
3091 bot = hex_digit_to_int(hex[i+1]);
3092 if (top == -1 || bot == -1) {
3093 PyErr_Format(PyExc_ValueError,
3094 "non-hexadecimal number found in "
3095 "fromhex() arg at position %zd", i);
3096 goto error;
3097 }
3098 buf[j++] = (top << 4) + bot;
3099 }
3100 if (PyByteArray_Resize(newbytes, j) < 0)
3101 goto error;
3102 return newbytes;
3103
3104 error:
3105 Py_DECREF(newbytes);
3106 return NULL;
3107}
3108
3109PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
3110
3111static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003112bytearray_reduce(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00003113{
3114 PyObject *latin1, *dict;
3115 if (self->ob_bytes)
Benjamin Peterson78821dd2009-01-25 17:15:10 +00003116#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00003117 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
3118 Py_SIZE(self), NULL);
Benjamin Peterson78821dd2009-01-25 17:15:10 +00003119#else
3120 latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self))
3121#endif
Christian Heimes44720832008-05-26 13:01:01 +00003122 else
Benjamin Peterson78821dd2009-01-25 17:15:10 +00003123#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00003124 latin1 = PyUnicode_FromString("");
Benjamin Peterson78821dd2009-01-25 17:15:10 +00003125#else
3126 latin1 = PyString_FromString("");
3127#endif
Christian Heimes44720832008-05-26 13:01:01 +00003128
3129 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
3130 if (dict == NULL) {
3131 PyErr_Clear();
3132 dict = Py_None;
3133 Py_INCREF(dict);
3134 }
3135
3136 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
3137}
3138
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00003139PyDoc_STRVAR(sizeof_doc,
3140"B.__sizeof__() -> int\n\
3141 \n\
3142Returns the size of B in memory, in bytes");
3143static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003144bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00003145{
Georg Brandl517cfdc2009-04-05 13:16:35 +00003146 Py_ssize_t res;
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00003147
Georg Brandl517cfdc2009-04-05 13:16:35 +00003148 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
3149 return PyInt_FromSsize_t(res);
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00003150}
3151
Benjamin Petersond6720012009-04-18 15:31:34 +00003152static PySequenceMethods bytearray_as_sequence = {
3153 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes44720832008-05-26 13:01:01 +00003154 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Petersond6720012009-04-18 15:31:34 +00003155 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
3156 (ssizeargfunc)bytearray_getitem, /* sq_item */
3157 0, /* sq_slice */
3158 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
3159 0, /* sq_ass_slice */
3160 (objobjproc)bytearray_contains, /* sq_contains */
3161 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
3162 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes44720832008-05-26 13:01:01 +00003163};
3164
Benjamin Petersond6720012009-04-18 15:31:34 +00003165static PyMappingMethods bytearray_as_mapping = {
3166 (lenfunc)bytearray_length,
3167 (binaryfunc)bytearray_subscript,
3168 (objobjargproc)bytearray_ass_subscript,
Christian Heimes44720832008-05-26 13:01:01 +00003169};
3170
Benjamin Petersond6720012009-04-18 15:31:34 +00003171static PyBufferProcs bytearray_as_buffer = {
3172 (readbufferproc)bytearray_buffer_getreadbuf,
3173 (writebufferproc)bytearray_buffer_getwritebuf,
3174 (segcountproc)bytearray_buffer_getsegcount,
3175 (charbufferproc)bytearray_buffer_getcharbuf,
3176 (getbufferproc)bytearray_getbuffer,
3177 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes44720832008-05-26 13:01:01 +00003178};
3179
3180static PyMethodDef
Benjamin Petersond6720012009-04-18 15:31:34 +00003181bytearray_methods[] = {
3182 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
3183 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
3184 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
3185 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00003186 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
3187 _Py_capitalize__doc__},
3188 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00003189 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
3190 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS, decode_doc},
3191 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00003192 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
3193 expandtabs__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00003194 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
3195 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
3196 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes44720832008-05-26 13:01:01 +00003197 fromhex_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00003198 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
3199 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00003200 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
3201 _Py_isalnum__doc__},
3202 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
3203 _Py_isalpha__doc__},
3204 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
3205 _Py_isdigit__doc__},
3206 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
3207 _Py_islower__doc__},
3208 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
3209 _Py_isspace__doc__},
3210 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
3211 _Py_istitle__doc__},
3212 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
3213 _Py_isupper__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00003214 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes44720832008-05-26 13:01:01 +00003215 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
3216 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00003217 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
3218 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
3219 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
3220 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
3221 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
3222 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
3223 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
3224 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00003225 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00003226 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
3227 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
3228 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
3229 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00003230 {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS,
3231 splitlines__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00003232 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes44720832008-05-26 13:01:01 +00003233 startswith__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00003234 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00003235 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
3236 _Py_swapcase__doc__},
3237 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00003238 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00003239 translate__doc__},
3240 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
3241 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
3242 {NULL}
3243};
3244
Benjamin Petersond6720012009-04-18 15:31:34 +00003245PyDoc_STRVAR(bytearray_doc,
Christian Heimes44720832008-05-26 13:01:01 +00003246"bytearray(iterable_of_ints) -> bytearray.\n\
3247bytearray(string, encoding[, errors]) -> bytearray.\n\
3248bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
3249bytearray(memory_view) -> bytearray.\n\
3250\n\
3251Construct an mutable bytearray object from:\n\
3252 - an iterable yielding integers in range(256)\n\
3253 - a text string encoded using the specified encoding\n\
3254 - a bytes or a bytearray object\n\
3255 - any object implementing the buffer API.\n\
3256\n\
3257bytearray(int) -> bytearray.\n\
3258\n\
3259Construct a zero-initialized bytearray of the given length.");
3260
3261
Benjamin Petersond6720012009-04-18 15:31:34 +00003262static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes44720832008-05-26 13:01:01 +00003263
3264PyTypeObject PyByteArray_Type = {
3265 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3266 "bytearray",
3267 sizeof(PyByteArrayObject),
3268 0,
Benjamin Petersond6720012009-04-18 15:31:34 +00003269 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00003270 0, /* tp_print */
3271 0, /* tp_getattr */
3272 0, /* tp_setattr */
3273 0, /* tp_compare */
Benjamin Petersond6720012009-04-18 15:31:34 +00003274 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes44720832008-05-26 13:01:01 +00003275 0, /* tp_as_number */
Benjamin Petersond6720012009-04-18 15:31:34 +00003276 &bytearray_as_sequence, /* tp_as_sequence */
3277 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes44720832008-05-26 13:01:01 +00003278 0, /* tp_hash */
3279 0, /* tp_call */
Benjamin Petersond6720012009-04-18 15:31:34 +00003280 bytearray_str, /* tp_str */
Christian Heimes44720832008-05-26 13:01:01 +00003281 PyObject_GenericGetAttr, /* tp_getattro */
3282 0, /* tp_setattro */
Benjamin Petersond6720012009-04-18 15:31:34 +00003283 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes44720832008-05-26 13:01:01 +00003284 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
3285 Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
Benjamin Petersond6720012009-04-18 15:31:34 +00003286 bytearray_doc, /* tp_doc */
Christian Heimes44720832008-05-26 13:01:01 +00003287 0, /* tp_traverse */
3288 0, /* tp_clear */
Benjamin Petersond6720012009-04-18 15:31:34 +00003289 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes44720832008-05-26 13:01:01 +00003290 0, /* tp_weaklistoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00003291 bytearray_iter, /* tp_iter */
Christian Heimes44720832008-05-26 13:01:01 +00003292 0, /* tp_iternext */
Benjamin Petersond6720012009-04-18 15:31:34 +00003293 bytearray_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00003294 0, /* tp_members */
3295 0, /* tp_getset */
3296 0, /* tp_base */
3297 0, /* tp_dict */
3298 0, /* tp_descr_get */
3299 0, /* tp_descr_set */
3300 0, /* tp_dictoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00003301 (initproc)bytearray_init, /* tp_init */
Christian Heimes44720832008-05-26 13:01:01 +00003302 PyType_GenericAlloc, /* tp_alloc */
3303 PyType_GenericNew, /* tp_new */
3304 PyObject_Del, /* tp_free */
3305};
3306
3307/*********************** Bytes Iterator ****************************/
3308
3309typedef struct {
3310 PyObject_HEAD
3311 Py_ssize_t it_index;
3312 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
3313} bytesiterobject;
3314
3315static void
Benjamin Petersond6720012009-04-18 15:31:34 +00003316bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00003317{
3318 _PyObject_GC_UNTRACK(it);
3319 Py_XDECREF(it->it_seq);
3320 PyObject_GC_Del(it);
3321}
3322
3323static int
Benjamin Petersond6720012009-04-18 15:31:34 +00003324bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes44720832008-05-26 13:01:01 +00003325{
3326 Py_VISIT(it->it_seq);
3327 return 0;
3328}
3329
3330static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003331bytearrayiter_next(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00003332{
3333 PyByteArrayObject *seq;
3334 PyObject *item;
3335
3336 assert(it != NULL);
3337 seq = it->it_seq;
3338 if (seq == NULL)
3339 return NULL;
3340 assert(PyByteArray_Check(seq));
3341
3342 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
3343 item = PyInt_FromLong(
3344 (unsigned char)seq->ob_bytes[it->it_index]);
3345 if (item != NULL)
3346 ++it->it_index;
3347 return item;
3348 }
3349
3350 Py_DECREF(seq);
3351 it->it_seq = NULL;
3352 return NULL;
3353}
3354
3355static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003356bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00003357{
3358 Py_ssize_t len = 0;
3359 if (it->it_seq)
3360 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3361 return PyInt_FromSsize_t(len);
3362}
3363
3364PyDoc_STRVAR(length_hint_doc,
3365 "Private method returning an estimate of len(list(it)).");
3366
Benjamin Petersond6720012009-04-18 15:31:34 +00003367static PyMethodDef bytearrayiter_methods[] = {
3368 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes44720832008-05-26 13:01:01 +00003369 length_hint_doc},
3370 {NULL, NULL} /* sentinel */
3371};
3372
3373PyTypeObject PyByteArrayIter_Type = {
3374 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3375 "bytearray_iterator", /* tp_name */
3376 sizeof(bytesiterobject), /* tp_basicsize */
3377 0, /* tp_itemsize */
3378 /* methods */
Benjamin Petersond6720012009-04-18 15:31:34 +00003379 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00003380 0, /* tp_print */
3381 0, /* tp_getattr */
3382 0, /* tp_setattr */
3383 0, /* tp_compare */
3384 0, /* tp_repr */
3385 0, /* tp_as_number */
3386 0, /* tp_as_sequence */
3387 0, /* tp_as_mapping */
3388 0, /* tp_hash */
3389 0, /* tp_call */
3390 0, /* tp_str */
3391 PyObject_GenericGetAttr, /* tp_getattro */
3392 0, /* tp_setattro */
3393 0, /* tp_as_buffer */
3394 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3395 0, /* tp_doc */
Benjamin Petersond6720012009-04-18 15:31:34 +00003396 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes44720832008-05-26 13:01:01 +00003397 0, /* tp_clear */
3398 0, /* tp_richcompare */
3399 0, /* tp_weaklistoffset */
3400 PyObject_SelfIter, /* tp_iter */
Benjamin Petersond6720012009-04-18 15:31:34 +00003401 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3402 bytearrayiter_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00003403 0,
3404};
3405
3406static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003407bytearray_iter(PyObject *seq)
Christian Heimes44720832008-05-26 13:01:01 +00003408{
3409 bytesiterobject *it;
3410
3411 if (!PyByteArray_Check(seq)) {
3412 PyErr_BadInternalCall();
3413 return NULL;
3414 }
3415 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3416 if (it == NULL)
3417 return NULL;
3418 it->it_index = 0;
3419 Py_INCREF(seq);
3420 it->it_seq = (PyByteArrayObject *)seq;
3421 _PyObject_GC_TRACK(it);
3422 return (PyObject *)it;
3423}