blob: a842f47925d2ae827825f7d9884c300914cd86ae [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
Antoine Pitroue80a6a42010-01-17 12:26:20 +00008char _PyByteArray_empty_string[] = "";
Christian Heimes44720832008-05-26 13:01:01 +00009
10void
11PyByteArray_Fini(void)
12{
Christian Heimes44720832008-05-26 13:01:01 +000013}
14
15int
16PyByteArray_Init(void)
17{
Christian Heimes44720832008-05-26 13:01:01 +000018 return 1;
19}
20
21/* end nullbytes support */
22
23/* Helpers */
24
25static int
26_getbytevalue(PyObject* arg, int *value)
27{
28 long face_value;
29
Georg Brandl3e483f62008-07-16 22:57:41 +000030 if (PyBytes_CheckExact(arg)) {
Christian Heimes44720832008-05-26 13:01:01 +000031 if (Py_SIZE(arg) != 1) {
32 PyErr_SetString(PyExc_ValueError, "string must be of size 1");
33 return 0;
34 }
Georg Brandl3e483f62008-07-16 22:57:41 +000035 *value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
36 return 1;
37 }
38 else if (PyInt_Check(arg) || PyLong_Check(arg)) {
39 face_value = PyLong_AsLong(arg);
Christian Heimes44720832008-05-26 13:01:01 +000040 }
41 else {
Georg Brandl3e483f62008-07-16 22:57:41 +000042 PyObject *index = PyNumber_Index(arg);
43 if (index == NULL) {
44 PyErr_Format(PyExc_TypeError,
45 "an integer or string of size 1 is required");
46 return 0;
47 }
48 face_value = PyLong_AsLong(index);
49 Py_DECREF(index);
50 }
Georg Brandl3e483f62008-07-16 22:57:41 +000051
52 if (face_value < 0 || face_value >= 256) {
Georg Brandl3238a3e2008-07-16 23:17:46 +000053 /* this includes the OverflowError in case the long is too large */
Georg Brandl3e483f62008-07-16 22:57:41 +000054 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Christian Heimes44720832008-05-26 13:01:01 +000055 return 0;
56 }
57
58 *value = face_value;
59 return 1;
60}
61
62static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000063bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000064{
65 if ( index != 0 ) {
66 PyErr_SetString(PyExc_SystemError,
67 "accessing non-existent bytes segment");
68 return -1;
69 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +000070 *ptr = (void *)PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +000071 return Py_SIZE(self);
72}
73
74static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000075bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000076{
77 if ( index != 0 ) {
78 PyErr_SetString(PyExc_SystemError,
79 "accessing non-existent bytes segment");
80 return -1;
81 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +000082 *ptr = (void *)PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +000083 return Py_SIZE(self);
84}
85
86static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000087bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
Christian Heimes44720832008-05-26 13:01:01 +000088{
89 if ( lenp )
90 *lenp = Py_SIZE(self);
91 return 1;
92}
93
94static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000095bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000096{
97 if ( index != 0 ) {
98 PyErr_SetString(PyExc_SystemError,
99 "accessing non-existent bytes segment");
100 return -1;
101 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000102 *ptr = PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +0000103 return Py_SIZE(self);
104}
105
106static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000107bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes44720832008-05-26 13:01:01 +0000108{
109 int ret;
110 void *ptr;
111 if (view == NULL) {
112 obj->ob_exports++;
113 return 0;
114 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000115 ptr = (void *) PyByteArray_AS_STRING(obj);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000116 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
Christian Heimes44720832008-05-26 13:01:01 +0000117 if (ret >= 0) {
118 obj->ob_exports++;
119 }
120 return ret;
121}
122
123static void
Benjamin Petersond6720012009-04-18 15:31:34 +0000124bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes44720832008-05-26 13:01:01 +0000125{
126 obj->ob_exports--;
127}
128
129static Py_ssize_t
130_getbuffer(PyObject *obj, Py_buffer *view)
131{
132 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
133
134 if (buffer == NULL || buffer->bf_getbuffer == NULL)
135 {
136 PyErr_Format(PyExc_TypeError,
137 "Type %.100s doesn't support the buffer API",
138 Py_TYPE(obj)->tp_name);
139 return -1;
140 }
141
142 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
143 return -1;
144 return view->len;
145}
146
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000147static int
148_canresize(PyByteArrayObject *self)
149{
150 if (self->ob_exports > 0) {
151 PyErr_SetString(PyExc_BufferError,
152 "Existing exports of data: object cannot be re-sized");
153 return 0;
154 }
155 return 1;
156}
157
Christian Heimes44720832008-05-26 13:01:01 +0000158/* Direct API functions */
159
160PyObject *
161PyByteArray_FromObject(PyObject *input)
162{
163 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
164 input, NULL);
165}
166
167PyObject *
168PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
169{
170 PyByteArrayObject *new;
171 Py_ssize_t alloc;
172
173 if (size < 0) {
174 PyErr_SetString(PyExc_SystemError,
175 "Negative size passed to PyByteArray_FromStringAndSize");
176 return NULL;
177 }
178
179 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
180 if (new == NULL)
181 return NULL;
182
183 if (size == 0) {
184 new->ob_bytes = NULL;
185 alloc = 0;
186 }
187 else {
188 alloc = size + 1;
189 new->ob_bytes = PyMem_Malloc(alloc);
190 if (new->ob_bytes == NULL) {
191 Py_DECREF(new);
192 return PyErr_NoMemory();
193 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000194 if (bytes != NULL && size > 0)
Christian Heimes44720832008-05-26 13:01:01 +0000195 memcpy(new->ob_bytes, bytes, size);
196 new->ob_bytes[size] = '\0'; /* Trailing null byte */
197 }
198 Py_SIZE(new) = size;
199 new->ob_alloc = alloc;
200 new->ob_exports = 0;
201
202 return (PyObject *)new;
203}
204
205Py_ssize_t
206PyByteArray_Size(PyObject *self)
207{
208 assert(self != NULL);
209 assert(PyByteArray_Check(self));
210
211 return PyByteArray_GET_SIZE(self);
212}
213
214char *
215PyByteArray_AsString(PyObject *self)
216{
217 assert(self != NULL);
218 assert(PyByteArray_Check(self));
219
220 return PyByteArray_AS_STRING(self);
221}
222
223int
224PyByteArray_Resize(PyObject *self, Py_ssize_t size)
225{
226 void *sval;
227 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
228
229 assert(self != NULL);
230 assert(PyByteArray_Check(self));
231 assert(size >= 0);
232
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000233 if (size == Py_SIZE(self)) {
234 return 0;
235 }
236 if (!_canresize((PyByteArrayObject *)self)) {
237 return -1;
238 }
239
Christian Heimes44720832008-05-26 13:01:01 +0000240 if (size < alloc / 2) {
241 /* Major downsize; resize down to exact size */
242 alloc = size + 1;
243 }
244 else if (size < alloc) {
245 /* Within allocated size; quick exit */
246 Py_SIZE(self) = size;
247 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
248 return 0;
249 }
250 else if (size <= alloc * 1.125) {
251 /* Moderate upsize; overallocate similar to list_resize() */
252 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
253 }
254 else {
255 /* Major upsize; resize up to exact size */
256 alloc = size + 1;
257 }
258
Christian Heimes44720832008-05-26 13:01:01 +0000259 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
260 if (sval == NULL) {
261 PyErr_NoMemory();
262 return -1;
263 }
264
265 ((PyByteArrayObject *)self)->ob_bytes = sval;
266 Py_SIZE(self) = size;
267 ((PyByteArrayObject *)self)->ob_alloc = alloc;
268 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
269
270 return 0;
271}
272
273PyObject *
274PyByteArray_Concat(PyObject *a, PyObject *b)
275{
276 Py_ssize_t size;
277 Py_buffer va, vb;
278 PyByteArrayObject *result = NULL;
279
280 va.len = -1;
281 vb.len = -1;
282 if (_getbuffer(a, &va) < 0 ||
283 _getbuffer(b, &vb) < 0) {
284 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
285 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
286 goto done;
287 }
288
289 size = va.len + vb.len;
290 if (size < 0) {
Hirokazu Yamamotoa3e6c972009-03-05 09:34:14 +0000291 PyErr_NoMemory();
Christian Heimes44720832008-05-26 13:01:01 +0000292 goto done;
293 }
294
295 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
296 if (result != NULL) {
297 memcpy(result->ob_bytes, va.buf, va.len);
298 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
299 }
300
301 done:
302 if (va.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000303 PyBuffer_Release(&va);
Christian Heimes44720832008-05-26 13:01:01 +0000304 if (vb.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000305 PyBuffer_Release(&vb);
Christian Heimes44720832008-05-26 13:01:01 +0000306 return (PyObject *)result;
307}
308
309/* Functions stuffed into the type object */
310
311static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +0000312bytearray_length(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000313{
314 return Py_SIZE(self);
315}
316
317static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000318bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes44720832008-05-26 13:01:01 +0000319{
320 Py_ssize_t mysize;
321 Py_ssize_t size;
322 Py_buffer vo;
323
324 if (_getbuffer(other, &vo) < 0) {
325 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
326 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
327 return NULL;
328 }
329
330 mysize = Py_SIZE(self);
331 size = mysize + vo.len;
332 if (size < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000333 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000334 return PyErr_NoMemory();
335 }
336 if (size < self->ob_alloc) {
337 Py_SIZE(self) = size;
338 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
339 }
340 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000341 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000342 return NULL;
343 }
344 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000345 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000346 Py_INCREF(self);
347 return (PyObject *)self;
348}
349
350static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000351bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000352{
353 PyByteArrayObject *result;
354 Py_ssize_t mysize;
355 Py_ssize_t size;
356
357 if (count < 0)
358 count = 0;
359 mysize = Py_SIZE(self);
360 size = mysize * count;
361 if (count != 0 && size / count != mysize)
362 return PyErr_NoMemory();
363 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
364 if (result != NULL && size != 0) {
365 if (mysize == 1)
366 memset(result->ob_bytes, self->ob_bytes[0], size);
367 else {
368 Py_ssize_t i;
369 for (i = 0; i < count; i++)
370 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
371 }
372 }
373 return (PyObject *)result;
374}
375
376static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000377bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000378{
379 Py_ssize_t mysize;
380 Py_ssize_t size;
381
382 if (count < 0)
383 count = 0;
384 mysize = Py_SIZE(self);
385 size = mysize * count;
386 if (count != 0 && size / count != mysize)
387 return PyErr_NoMemory();
388 if (size < self->ob_alloc) {
389 Py_SIZE(self) = size;
390 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
391 }
392 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
393 return NULL;
394
395 if (mysize == 1)
396 memset(self->ob_bytes, self->ob_bytes[0], size);
397 else {
398 Py_ssize_t i;
399 for (i = 1; i < count; i++)
400 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
401 }
402
403 Py_INCREF(self);
404 return (PyObject *)self;
405}
406
407static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000408bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes44720832008-05-26 13:01:01 +0000409{
410 if (i < 0)
411 i += Py_SIZE(self);
412 if (i < 0 || i >= Py_SIZE(self)) {
413 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
414 return NULL;
415 }
416 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
417}
418
419static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000420bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes44720832008-05-26 13:01:01 +0000421{
Georg Brandl3e483f62008-07-16 22:57:41 +0000422 if (PyIndex_Check(index)) {
423 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000424
425 if (i == -1 && PyErr_Occurred())
426 return NULL;
427
428 if (i < 0)
429 i += PyByteArray_GET_SIZE(self);
430
431 if (i < 0 || i >= Py_SIZE(self)) {
432 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
433 return NULL;
434 }
435 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
436 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000437 else if (PySlice_Check(index)) {
Christian Heimes44720832008-05-26 13:01:01 +0000438 Py_ssize_t start, stop, step, slicelength, cur, i;
Georg Brandl3e483f62008-07-16 22:57:41 +0000439 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes44720832008-05-26 13:01:01 +0000440 PyByteArray_GET_SIZE(self),
441 &start, &stop, &step, &slicelength) < 0) {
442 return NULL;
443 }
444
445 if (slicelength <= 0)
446 return PyByteArray_FromStringAndSize("", 0);
447 else if (step == 1) {
448 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
449 slicelength);
450 }
451 else {
452 char *source_buf = PyByteArray_AS_STRING(self);
453 char *result_buf = (char *)PyMem_Malloc(slicelength);
454 PyObject *result;
455
456 if (result_buf == NULL)
457 return PyErr_NoMemory();
458
459 for (cur = start, i = 0; i < slicelength;
460 cur += step, i++) {
461 result_buf[i] = source_buf[cur];
462 }
463 result = PyByteArray_FromStringAndSize(result_buf, slicelength);
464 PyMem_Free(result_buf);
465 return result;
466 }
467 }
468 else {
469 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
470 return NULL;
471 }
472}
473
474static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000475bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes44720832008-05-26 13:01:01 +0000476 PyObject *values)
477{
478 Py_ssize_t avail, needed;
479 void *bytes;
480 Py_buffer vbytes;
481 int res = 0;
482
483 vbytes.len = -1;
484 if (values == (PyObject *)self) {
485 /* Make a copy and call this function recursively */
486 int err;
487 values = PyByteArray_FromObject(values);
488 if (values == NULL)
489 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000490 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes44720832008-05-26 13:01:01 +0000491 Py_DECREF(values);
492 return err;
493 }
494 if (values == NULL) {
495 /* del b[lo:hi] */
496 bytes = NULL;
497 needed = 0;
498 }
499 else {
500 if (_getbuffer(values, &vbytes) < 0) {
501 PyErr_Format(PyExc_TypeError,
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000502 "can't set bytearray slice from %.100s",
Christian Heimes44720832008-05-26 13:01:01 +0000503 Py_TYPE(values)->tp_name);
504 return -1;
505 }
506 needed = vbytes.len;
507 bytes = vbytes.buf;
508 }
509
510 if (lo < 0)
511 lo = 0;
512 if (hi < lo)
513 hi = lo;
514 if (hi > Py_SIZE(self))
515 hi = Py_SIZE(self);
516
517 avail = hi - lo;
518 if (avail < 0)
519 lo = hi = avail = 0;
520
521 if (avail != needed) {
522 if (avail > needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000523 if (!_canresize(self)) {
524 res = -1;
525 goto finish;
526 }
Christian Heimes44720832008-05-26 13:01:01 +0000527 /*
528 0 lo hi old_size
529 | |<----avail----->|<-----tomove------>|
530 | |<-needed->|<-----tomove------>|
531 0 lo new_hi new_size
532 */
533 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
534 Py_SIZE(self) - hi);
535 }
536 /* XXX(nnorwitz): need to verify this can't overflow! */
537 if (PyByteArray_Resize((PyObject *)self,
538 Py_SIZE(self) + needed - avail) < 0) {
539 res = -1;
540 goto finish;
541 }
542 if (avail < needed) {
543 /*
544 0 lo hi old_size
545 | |<-avail->|<-----tomove------>|
546 | |<----needed---->|<-----tomove------>|
547 0 lo new_hi new_size
548 */
549 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
550 Py_SIZE(self) - lo - needed);
551 }
552 }
553
554 if (needed > 0)
555 memcpy(self->ob_bytes + lo, bytes, needed);
556
557
558 finish:
559 if (vbytes.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000560 PyBuffer_Release(&vbytes);
Christian Heimes44720832008-05-26 13:01:01 +0000561 return res;
562}
563
564static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000565bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes44720832008-05-26 13:01:01 +0000566{
567 int ival;
568
569 if (i < 0)
570 i += Py_SIZE(self);
571
572 if (i < 0 || i >= Py_SIZE(self)) {
573 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
574 return -1;
575 }
576
577 if (value == NULL)
Benjamin Petersond6720012009-04-18 15:31:34 +0000578 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes44720832008-05-26 13:01:01 +0000579
580 if (!_getbytevalue(value, &ival))
581 return -1;
582
583 self->ob_bytes[i] = ival;
584 return 0;
585}
586
587static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000588bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes44720832008-05-26 13:01:01 +0000589{
590 Py_ssize_t start, stop, step, slicelen, needed;
591 char *bytes;
592
Georg Brandl3e483f62008-07-16 22:57:41 +0000593 if (PyIndex_Check(index)) {
594 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000595
596 if (i == -1 && PyErr_Occurred())
597 return -1;
598
599 if (i < 0)
600 i += PyByteArray_GET_SIZE(self);
601
602 if (i < 0 || i >= Py_SIZE(self)) {
603 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
604 return -1;
605 }
606
607 if (values == NULL) {
608 /* Fall through to slice assignment */
609 start = i;
610 stop = i + 1;
611 step = 1;
612 slicelen = 1;
613 }
614 else {
Georg Brandl3e483f62008-07-16 22:57:41 +0000615 int ival;
616 if (!_getbytevalue(values, &ival))
Christian Heimes44720832008-05-26 13:01:01 +0000617 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000618 self->ob_bytes[i] = (char)ival;
619 return 0;
620 }
621 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000622 else if (PySlice_Check(index)) {
623 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes44720832008-05-26 13:01:01 +0000624 PyByteArray_GET_SIZE(self),
625 &start, &stop, &step, &slicelen) < 0) {
626 return -1;
627 }
628 }
629 else {
630 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
631 return -1;
632 }
633
634 if (values == NULL) {
635 bytes = NULL;
636 needed = 0;
637 }
638 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
639 /* Make a copy an call this function recursively */
640 int err;
641 values = PyByteArray_FromObject(values);
642 if (values == NULL)
643 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000644 err = bytearray_ass_subscript(self, index, values);
Christian Heimes44720832008-05-26 13:01:01 +0000645 Py_DECREF(values);
646 return err;
647 }
648 else {
649 assert(PyByteArray_Check(values));
650 bytes = ((PyByteArrayObject *)values)->ob_bytes;
651 needed = Py_SIZE(values);
652 }
653 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
654 if ((step < 0 && start < stop) ||
655 (step > 0 && start > stop))
656 stop = start;
657 if (step == 1) {
658 if (slicelen != needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000659 if (!_canresize(self))
660 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000661 if (slicelen > needed) {
662 /*
663 0 start stop old_size
664 | |<---slicelen--->|<-----tomove------>|
665 | |<-needed->|<-----tomove------>|
666 0 lo new_hi new_size
667 */
668 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
669 Py_SIZE(self) - stop);
670 }
671 if (PyByteArray_Resize((PyObject *)self,
672 Py_SIZE(self) + needed - slicelen) < 0)
673 return -1;
674 if (slicelen < needed) {
675 /*
676 0 lo hi old_size
677 | |<-avail->|<-----tomove------>|
678 | |<----needed---->|<-----tomove------>|
679 0 lo new_hi new_size
680 */
681 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
682 Py_SIZE(self) - start - needed);
683 }
684 }
685
686 if (needed > 0)
687 memcpy(self->ob_bytes + start, bytes, needed);
688
689 return 0;
690 }
691 else {
692 if (needed == 0) {
693 /* Delete slice */
Mark Dickinson36ecd672010-01-29 17:11:39 +0000694 size_t cur;
695 Py_ssize_t i;
Christian Heimes44720832008-05-26 13:01:01 +0000696
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000697 if (!_canresize(self))
698 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000699 if (step < 0) {
700 stop = start + 1;
701 start = stop + step * (slicelen - 1) - 1;
702 step = -step;
703 }
704 for (cur = start, i = 0;
705 i < slicelen; cur += step, i++) {
706 Py_ssize_t lim = step - 1;
707
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000708 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes44720832008-05-26 13:01:01 +0000709 lim = PyByteArray_GET_SIZE(self) - cur - 1;
710
711 memmove(self->ob_bytes + cur - i,
712 self->ob_bytes + cur + 1, lim);
713 }
714 /* Move the tail of the bytes, in one chunk */
715 cur = start + slicelen*step;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000716 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Christian Heimes44720832008-05-26 13:01:01 +0000717 memmove(self->ob_bytes + cur - slicelen,
718 self->ob_bytes + cur,
719 PyByteArray_GET_SIZE(self) - cur);
720 }
721 if (PyByteArray_Resize((PyObject *)self,
722 PyByteArray_GET_SIZE(self) - slicelen) < 0)
723 return -1;
724
725 return 0;
726 }
727 else {
728 /* Assign slice */
729 Py_ssize_t cur, i;
730
731 if (needed != slicelen) {
732 PyErr_Format(PyExc_ValueError,
733 "attempt to assign bytes of size %zd "
734 "to extended slice of size %zd",
735 needed, slicelen);
736 return -1;
737 }
738 for (cur = start, i = 0; i < slicelen; cur += step, i++)
739 self->ob_bytes[cur] = bytes[i];
740 return 0;
741 }
742 }
743}
744
745static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000746bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes44720832008-05-26 13:01:01 +0000747{
748 static char *kwlist[] = {"source", "encoding", "errors", 0};
749 PyObject *arg = NULL;
750 const char *encoding = NULL;
751 const char *errors = NULL;
752 Py_ssize_t count;
753 PyObject *it;
754 PyObject *(*iternext)(PyObject *);
755
756 if (Py_SIZE(self) != 0) {
757 /* Empty previous contents (yes, do this first of all!) */
758 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
759 return -1;
760 }
761
762 /* Parse arguments */
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000763 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes44720832008-05-26 13:01:01 +0000764 &arg, &encoding, &errors))
765 return -1;
766
767 /* Make a quick exit if no first argument */
768 if (arg == NULL) {
769 if (encoding != NULL || errors != NULL) {
770 PyErr_SetString(PyExc_TypeError,
771 "encoding or errors without sequence argument");
772 return -1;
773 }
774 return 0;
775 }
776
777 if (PyBytes_Check(arg)) {
778 PyObject *new, *encoded;
779 if (encoding != NULL) {
780 encoded = PyCodec_Encode(arg, encoding, errors);
781 if (encoded == NULL)
782 return -1;
783 assert(PyBytes_Check(encoded));
784 }
785 else {
786 encoded = arg;
787 Py_INCREF(arg);
788 }
Benjamin Petersond6720012009-04-18 15:31:34 +0000789 new = bytearray_iconcat(self, arg);
Christian Heimes44720832008-05-26 13:01:01 +0000790 Py_DECREF(encoded);
791 if (new == NULL)
792 return -1;
793 Py_DECREF(new);
794 return 0;
795 }
796
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000797#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +0000798 if (PyUnicode_Check(arg)) {
799 /* Encode via the codec registry */
800 PyObject *encoded, *new;
801 if (encoding == NULL) {
802 PyErr_SetString(PyExc_TypeError,
803 "unicode argument without an encoding");
804 return -1;
805 }
806 encoded = PyCodec_Encode(arg, encoding, errors);
807 if (encoded == NULL)
808 return -1;
809 assert(PyBytes_Check(encoded));
Benjamin Petersond6720012009-04-18 15:31:34 +0000810 new = bytearray_iconcat(self, encoded);
Christian Heimes44720832008-05-26 13:01:01 +0000811 Py_DECREF(encoded);
812 if (new == NULL)
813 return -1;
814 Py_DECREF(new);
815 return 0;
816 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000817#endif
Christian Heimes44720832008-05-26 13:01:01 +0000818
819 /* If it's not unicode, there can't be encoding or errors */
820 if (encoding != NULL || errors != NULL) {
821 PyErr_SetString(PyExc_TypeError,
822 "encoding or errors without a string argument");
823 return -1;
824 }
825
826 /* Is it an int? */
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000827 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
828 if (count == -1 && PyErr_Occurred()) {
829 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes44720832008-05-26 13:01:01 +0000830 return -1;
Benjamin Petersonae530c22010-04-16 22:52:44 +0000831 PyErr_Clear();
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000832 }
833 else if (count < 0) {
834 PyErr_SetString(PyExc_ValueError, "negative count");
835 return -1;
836 }
837 else {
Christian Heimes44720832008-05-26 13:01:01 +0000838 if (count > 0) {
839 if (PyByteArray_Resize((PyObject *)self, count))
840 return -1;
841 memset(self->ob_bytes, 0, count);
842 }
843 return 0;
844 }
845
846 /* Use the buffer API */
847 if (PyObject_CheckBuffer(arg)) {
848 Py_ssize_t size;
849 Py_buffer view;
850 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
851 return -1;
852 size = view.len;
853 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
854 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
855 goto fail;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000856 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000857 return 0;
858 fail:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000859 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000860 return -1;
861 }
862
863 /* XXX Optimize this if the arguments is a list, tuple */
864
865 /* Get the iterator */
866 it = PyObject_GetIter(arg);
867 if (it == NULL)
868 return -1;
869 iternext = *Py_TYPE(it)->tp_iternext;
870
871 /* Run the iterator to exhaustion */
872 for (;;) {
873 PyObject *item;
Georg Brandl3e758462008-07-16 23:10:05 +0000874 int rc, value;
Christian Heimes44720832008-05-26 13:01:01 +0000875
876 /* Get the next item */
877 item = iternext(it);
878 if (item == NULL) {
879 if (PyErr_Occurred()) {
880 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
881 goto error;
882 PyErr_Clear();
883 }
884 break;
885 }
886
887 /* Interpret it as an int (__index__) */
Georg Brandl3e758462008-07-16 23:10:05 +0000888 rc = _getbytevalue(item, &value);
Christian Heimes44720832008-05-26 13:01:01 +0000889 Py_DECREF(item);
Georg Brandl3e758462008-07-16 23:10:05 +0000890 if (!rc)
Christian Heimes44720832008-05-26 13:01:01 +0000891 goto error;
892
Christian Heimes44720832008-05-26 13:01:01 +0000893 /* Append the byte */
894 if (Py_SIZE(self) < self->ob_alloc)
895 Py_SIZE(self)++;
896 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
897 goto error;
898 self->ob_bytes[Py_SIZE(self)-1] = value;
899 }
900
901 /* Clean up and return success */
902 Py_DECREF(it);
903 return 0;
904
905 error:
906 /* Error handling when it != NULL */
907 Py_DECREF(it);
908 return -1;
909}
910
911/* Mostly copied from string_repr, but without the
912 "smart quote" functionality. */
913static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000914bytearray_repr(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000915{
916 static const char *hexdigits = "0123456789abcdef";
917 const char *quote_prefix = "bytearray(b";
918 const char *quote_postfix = ")";
919 Py_ssize_t length = Py_SIZE(self);
920 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000921 size_t newsize;
Christian Heimes44720832008-05-26 13:01:01 +0000922 PyObject *v;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000923 if (length > (PY_SSIZE_T_MAX - 14) / 4) {
Christian Heimes44720832008-05-26 13:01:01 +0000924 PyErr_SetString(PyExc_OverflowError,
925 "bytearray object is too large to make repr");
926 return NULL;
927 }
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000928 newsize = 14 + 4 * length;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000929 v = PyString_FromStringAndSize(NULL, newsize);
Christian Heimes44720832008-05-26 13:01:01 +0000930 if (v == NULL) {
931 return NULL;
932 }
933 else {
934 register Py_ssize_t i;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000935 register char c;
936 register char *p;
Christian Heimes44720832008-05-26 13:01:01 +0000937 int quote;
938
939 /* Figure out which quote to use; single is preferred */
940 quote = '\'';
941 {
942 char *test, *start;
943 start = PyByteArray_AS_STRING(self);
944 for (test = start; test < start+length; ++test) {
945 if (*test == '"') {
946 quote = '\''; /* back to single */
947 goto decided;
948 }
949 else if (*test == '\'')
950 quote = '"';
951 }
952 decided:
953 ;
954 }
955
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000956 p = PyString_AS_STRING(v);
Christian Heimes44720832008-05-26 13:01:01 +0000957 while (*quote_prefix)
958 *p++ = *quote_prefix++;
959 *p++ = quote;
960
961 for (i = 0; i < length; i++) {
962 /* There's at least enough room for a hex escape
963 and a closing quote. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000964 assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
Christian Heimes44720832008-05-26 13:01:01 +0000965 c = self->ob_bytes[i];
966 if (c == '\'' || c == '\\')
967 *p++ = '\\', *p++ = c;
968 else if (c == '\t')
969 *p++ = '\\', *p++ = 't';
970 else if (c == '\n')
971 *p++ = '\\', *p++ = 'n';
972 else if (c == '\r')
973 *p++ = '\\', *p++ = 'r';
974 else if (c == 0)
975 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
976 else if (c < ' ' || c >= 0x7f) {
977 *p++ = '\\';
978 *p++ = 'x';
979 *p++ = hexdigits[(c & 0xf0) >> 4];
980 *p++ = hexdigits[c & 0xf];
981 }
982 else
983 *p++ = c;
984 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000985 assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
Christian Heimes44720832008-05-26 13:01:01 +0000986 *p++ = quote;
987 while (*quote_postfix) {
988 *p++ = *quote_postfix++;
989 }
990 *p = '\0';
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000991 if (_PyString_Resize(&v, (p - PyString_AS_STRING(v)))) {
Christian Heimes44720832008-05-26 13:01:01 +0000992 Py_DECREF(v);
993 return NULL;
994 }
995 return v;
996 }
997}
998
999static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001000bytearray_str(PyObject *op)
Christian Heimes44720832008-05-26 13:01:01 +00001001{
1002#if 0
1003 if (Py_BytesWarningFlag) {
1004 if (PyErr_WarnEx(PyExc_BytesWarning,
1005 "str() on a bytearray instance", 1))
1006 return NULL;
1007 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001008 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes44720832008-05-26 13:01:01 +00001009#endif
1010 return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
1011}
1012
1013static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001014bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes44720832008-05-26 13:01:01 +00001015{
1016 Py_ssize_t self_size, other_size;
1017 Py_buffer self_bytes, other_bytes;
1018 PyObject *res;
1019 Py_ssize_t minsize;
1020 int cmp;
1021
1022 /* Bytes can be compared to anything that supports the (binary)
1023 buffer API. Except that a comparison with Unicode is always an
1024 error, even if the comparison is for equality. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001025#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00001026 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1027 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
1028 if (Py_BytesWarningFlag && op == Py_EQ) {
1029 if (PyErr_WarnEx(PyExc_BytesWarning,
Ezio Melottid2342082010-01-14 11:34:10 +00001030 "Comparison between bytearray and string", 1))
Christian Heimes44720832008-05-26 13:01:01 +00001031 return NULL;
1032 }
1033
1034 Py_INCREF(Py_NotImplemented);
1035 return Py_NotImplemented;
1036 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001037#endif
Christian Heimes44720832008-05-26 13:01:01 +00001038
1039 self_size = _getbuffer(self, &self_bytes);
1040 if (self_size < 0) {
1041 PyErr_Clear();
1042 Py_INCREF(Py_NotImplemented);
1043 return Py_NotImplemented;
1044 }
1045
1046 other_size = _getbuffer(other, &other_bytes);
1047 if (other_size < 0) {
1048 PyErr_Clear();
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001049 PyBuffer_Release(&self_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001050 Py_INCREF(Py_NotImplemented);
1051 return Py_NotImplemented;
1052 }
1053
1054 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1055 /* Shortcut: if the lengths differ, the objects differ */
1056 cmp = (op == Py_NE);
1057 }
1058 else {
1059 minsize = self_size;
1060 if (other_size < minsize)
1061 minsize = other_size;
1062
1063 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1064 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1065
1066 if (cmp == 0) {
1067 if (self_size < other_size)
1068 cmp = -1;
1069 else if (self_size > other_size)
1070 cmp = 1;
1071 }
1072
1073 switch (op) {
1074 case Py_LT: cmp = cmp < 0; break;
1075 case Py_LE: cmp = cmp <= 0; break;
1076 case Py_EQ: cmp = cmp == 0; break;
1077 case Py_NE: cmp = cmp != 0; break;
1078 case Py_GT: cmp = cmp > 0; break;
1079 case Py_GE: cmp = cmp >= 0; break;
1080 }
1081 }
1082
1083 res = cmp ? Py_True : Py_False;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001084 PyBuffer_Release(&self_bytes);
1085 PyBuffer_Release(&other_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001086 Py_INCREF(res);
1087 return res;
1088}
1089
1090static void
Benjamin Petersond6720012009-04-18 15:31:34 +00001091bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00001092{
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001093 if (self->ob_exports > 0) {
1094 PyErr_SetString(PyExc_SystemError,
Georg Brandl517cfdc2009-04-05 13:16:35 +00001095 "deallocated bytearray object has exported buffers");
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001096 PyErr_Print();
1097 }
Christian Heimes44720832008-05-26 13:01:01 +00001098 if (self->ob_bytes != 0) {
1099 PyMem_Free(self->ob_bytes);
1100 }
1101 Py_TYPE(self)->tp_free((PyObject *)self);
1102}
1103
1104
1105/* -------------------------------------------------------------------- */
1106/* Methods */
1107
1108#define STRINGLIB_CHAR char
Christian Heimes44720832008-05-26 13:01:01 +00001109#define STRINGLIB_LEN PyByteArray_GET_SIZE
1110#define STRINGLIB_STR PyByteArray_AS_STRING
1111#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrou64672132010-01-13 07:55:48 +00001112#define STRINGLIB_ISSPACE Py_ISSPACE
1113#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes44720832008-05-26 13:01:01 +00001114#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1115#define STRINGLIB_MUTABLE 1
1116
1117#include "stringlib/fastsearch.h"
1118#include "stringlib/count.h"
1119#include "stringlib/find.h"
1120#include "stringlib/partition.h"
Antoine Pitrou64672132010-01-13 07:55:48 +00001121#include "stringlib/split.h"
Christian Heimes44720832008-05-26 13:01:01 +00001122#include "stringlib/ctype.h"
1123#include "stringlib/transmogrify.h"
1124
1125
1126/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1127were copied from the old char* style string object. */
1128
Antoine Pitrou64672132010-01-13 07:55:48 +00001129/* helper macro to fixup start/end slice values */
1130#define ADJUST_INDICES(start, end, len) \
1131 if (end > len) \
1132 end = len; \
1133 else if (end < 0) { \
1134 end += len; \
1135 if (end < 0) \
1136 end = 0; \
1137 } \
1138 if (start < 0) { \
1139 start += len; \
1140 if (start < 0) \
1141 start = 0; \
1142 }
Christian Heimes44720832008-05-26 13:01:01 +00001143
1144Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Petersond6720012009-04-18 15:31:34 +00001145bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes44720832008-05-26 13:01:01 +00001146{
1147 PyObject *subobj;
1148 Py_buffer subbuf;
1149 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1150 Py_ssize_t res;
1151
1152 if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
1153 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1154 return -2;
1155 if (_getbuffer(subobj, &subbuf) < 0)
1156 return -2;
1157 if (dir > 0)
1158 res = stringlib_find_slice(
1159 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1160 subbuf.buf, subbuf.len, start, end);
1161 else
1162 res = stringlib_rfind_slice(
1163 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1164 subbuf.buf, subbuf.len, start, end);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001165 PyBuffer_Release(&subbuf);
Christian Heimes44720832008-05-26 13:01:01 +00001166 return res;
1167}
1168
1169PyDoc_STRVAR(find__doc__,
1170"B.find(sub [,start [,end]]) -> int\n\
1171\n\
1172Return the lowest index in B where subsection sub is found,\n\
1173such that sub is contained within s[start,end]. Optional\n\
1174arguments start and end are interpreted as in slice notation.\n\
1175\n\
1176Return -1 on failure.");
1177
1178static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001179bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001180{
Benjamin Petersond6720012009-04-18 15:31:34 +00001181 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001182 if (result == -2)
1183 return NULL;
1184 return PyInt_FromSsize_t(result);
1185}
1186
1187PyDoc_STRVAR(count__doc__,
1188"B.count(sub [,start [,end]]) -> int\n\
1189\n\
1190Return the number of non-overlapping occurrences of subsection sub in\n\
1191bytes B[start:end]. Optional arguments start and end are interpreted\n\
1192as in slice notation.");
1193
1194static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001195bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001196{
1197 PyObject *sub_obj;
1198 const char *str = PyByteArray_AS_STRING(self);
1199 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1200 Py_buffer vsub;
1201 PyObject *count_obj;
1202
1203 if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1204 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1205 return NULL;
1206
1207 if (_getbuffer(sub_obj, &vsub) < 0)
1208 return NULL;
1209
Antoine Pitrou64672132010-01-13 07:55:48 +00001210 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes44720832008-05-26 13:01:01 +00001211
1212 count_obj = PyInt_FromSsize_t(
Antoine Pitrou64672132010-01-13 07:55:48 +00001213 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes44720832008-05-26 13:01:01 +00001214 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001215 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00001216 return count_obj;
1217}
1218
1219
1220PyDoc_STRVAR(index__doc__,
1221"B.index(sub [,start [,end]]) -> int\n\
1222\n\
1223Like B.find() but raise ValueError when the subsection is not found.");
1224
1225static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001226bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001227{
Benjamin Petersond6720012009-04-18 15:31:34 +00001228 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001229 if (result == -2)
1230 return NULL;
1231 if (result == -1) {
1232 PyErr_SetString(PyExc_ValueError,
1233 "subsection not found");
1234 return NULL;
1235 }
1236 return PyInt_FromSsize_t(result);
1237}
1238
1239
1240PyDoc_STRVAR(rfind__doc__,
1241"B.rfind(sub [,start [,end]]) -> int\n\
1242\n\
1243Return the highest index in B where subsection sub is found,\n\
1244such that sub is contained within s[start,end]. Optional\n\
1245arguments start and end are interpreted as in slice notation.\n\
1246\n\
1247Return -1 on failure.");
1248
1249static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001250bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001251{
Benjamin Petersond6720012009-04-18 15:31:34 +00001252 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001253 if (result == -2)
1254 return NULL;
1255 return PyInt_FromSsize_t(result);
1256}
1257
1258
1259PyDoc_STRVAR(rindex__doc__,
1260"B.rindex(sub [,start [,end]]) -> int\n\
1261\n\
1262Like B.rfind() but raise ValueError when the subsection is not found.");
1263
1264static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001265bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001266{
Benjamin Petersond6720012009-04-18 15:31:34 +00001267 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001268 if (result == -2)
1269 return NULL;
1270 if (result == -1) {
1271 PyErr_SetString(PyExc_ValueError,
1272 "subsection not found");
1273 return NULL;
1274 }
1275 return PyInt_FromSsize_t(result);
1276}
1277
1278
1279static int
Benjamin Petersond6720012009-04-18 15:31:34 +00001280bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00001281{
1282 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1283 if (ival == -1 && PyErr_Occurred()) {
1284 Py_buffer varg;
1285 int pos;
1286 PyErr_Clear();
1287 if (_getbuffer(arg, &varg) < 0)
1288 return -1;
1289 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1290 varg.buf, varg.len, 0);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001291 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00001292 return pos >= 0;
1293 }
1294 if (ival < 0 || ival >= 256) {
1295 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1296 return -1;
1297 }
1298
1299 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1300}
1301
1302
1303/* Matches the end (direction >= 0) or start (direction < 0) of self
1304 * against substr, using the start and end arguments. Returns
1305 * -1 on error, 0 if not found and 1 if found.
1306 */
1307Py_LOCAL(int)
Benjamin Petersond6720012009-04-18 15:31:34 +00001308_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes44720832008-05-26 13:01:01 +00001309 Py_ssize_t end, int direction)
1310{
1311 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1312 const char* str;
1313 Py_buffer vsubstr;
1314 int rv = 0;
1315
1316 str = PyByteArray_AS_STRING(self);
1317
1318 if (_getbuffer(substr, &vsubstr) < 0)
1319 return -1;
1320
Antoine Pitrou64672132010-01-13 07:55:48 +00001321 ADJUST_INDICES(start, end, len);
Christian Heimes44720832008-05-26 13:01:01 +00001322
1323 if (direction < 0) {
1324 /* startswith */
1325 if (start+vsubstr.len > len) {
1326 goto done;
1327 }
1328 } else {
1329 /* endswith */
1330 if (end-start < vsubstr.len || start > len) {
1331 goto done;
1332 }
1333
1334 if (end-vsubstr.len > start)
1335 start = end - vsubstr.len;
1336 }
1337 if (end-start >= vsubstr.len)
1338 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1339
1340done:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001341 PyBuffer_Release(&vsubstr);
Christian Heimes44720832008-05-26 13:01:01 +00001342 return rv;
1343}
1344
1345
1346PyDoc_STRVAR(startswith__doc__,
1347"B.startswith(prefix [,start [,end]]) -> bool\n\
1348\n\
1349Return True if B starts with the specified prefix, False otherwise.\n\
1350With optional start, test B beginning at that position.\n\
1351With optional end, stop comparing B at that position.\n\
1352prefix can also be a tuple of strings to try.");
1353
1354static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001355bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001356{
1357 Py_ssize_t start = 0;
1358 Py_ssize_t end = PY_SSIZE_T_MAX;
1359 PyObject *subobj;
1360 int result;
1361
1362 if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
1363 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1364 return NULL;
1365 if (PyTuple_Check(subobj)) {
1366 Py_ssize_t i;
1367 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001368 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001369 PyTuple_GET_ITEM(subobj, i),
1370 start, end, -1);
1371 if (result == -1)
1372 return NULL;
1373 else if (result) {
1374 Py_RETURN_TRUE;
1375 }
1376 }
1377 Py_RETURN_FALSE;
1378 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001379 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001380 if (result == -1)
1381 return NULL;
1382 else
1383 return PyBool_FromLong(result);
1384}
1385
1386PyDoc_STRVAR(endswith__doc__,
1387"B.endswith(suffix [,start [,end]]) -> bool\n\
1388\n\
1389Return True if B ends with the specified suffix, False otherwise.\n\
1390With optional start, test B beginning at that position.\n\
1391With optional end, stop comparing B at that position.\n\
1392suffix can also be a tuple of strings to try.");
1393
1394static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001395bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001396{
1397 Py_ssize_t start = 0;
1398 Py_ssize_t end = PY_SSIZE_T_MAX;
1399 PyObject *subobj;
1400 int result;
1401
1402 if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
1403 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1404 return NULL;
1405 if (PyTuple_Check(subobj)) {
1406 Py_ssize_t i;
1407 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001408 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001409 PyTuple_GET_ITEM(subobj, i),
1410 start, end, +1);
1411 if (result == -1)
1412 return NULL;
1413 else if (result) {
1414 Py_RETURN_TRUE;
1415 }
1416 }
1417 Py_RETURN_FALSE;
1418 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001419 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001420 if (result == -1)
1421 return NULL;
1422 else
1423 return PyBool_FromLong(result);
1424}
1425
1426
1427PyDoc_STRVAR(translate__doc__,
1428"B.translate(table[, deletechars]) -> bytearray\n\
1429\n\
1430Return a copy of B, where all characters occurring in the\n\
1431optional argument deletechars are removed, and the remaining\n\
1432characters have been mapped through the given translation\n\
1433table, which must be a bytes object of length 256.");
1434
1435static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001436bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001437{
1438 register char *input, *output;
1439 register const char *table;
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001440 register Py_ssize_t i, c;
Christian Heimes44720832008-05-26 13:01:01 +00001441 PyObject *input_obj = (PyObject*)self;
1442 const char *output_start;
1443 Py_ssize_t inlen;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001444 PyObject *result = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001445 int trans_table[256];
Georg Brandl6425a2f2008-12-28 11:54:53 +00001446 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001447 Py_buffer vtable, vdel;
1448
1449 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1450 &tableobj, &delobj))
1451 return NULL;
1452
Georg Brandl6425a2f2008-12-28 11:54:53 +00001453 if (tableobj == Py_None) {
1454 table = NULL;
1455 tableobj = NULL;
1456 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00001457 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001458 } else {
1459 if (vtable.len != 256) {
1460 PyErr_SetString(PyExc_ValueError,
1461 "translation table must be 256 characters long");
Georg Brandlec812ca2009-07-22 11:57:15 +00001462 PyBuffer_Release(&vtable);
1463 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001464 }
1465 table = (const char*)vtable.buf;
Christian Heimes44720832008-05-26 13:01:01 +00001466 }
1467
1468 if (delobj != NULL) {
1469 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandlec812ca2009-07-22 11:57:15 +00001470 if (tableobj != NULL)
1471 PyBuffer_Release(&vtable);
1472 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001473 }
1474 }
1475 else {
1476 vdel.buf = NULL;
1477 vdel.len = 0;
1478 }
1479
Christian Heimes44720832008-05-26 13:01:01 +00001480 inlen = PyByteArray_GET_SIZE(input_obj);
1481 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1482 if (result == NULL)
1483 goto done;
1484 output_start = output = PyByteArray_AsString(result);
1485 input = PyByteArray_AS_STRING(input_obj);
1486
Georg Brandl6425a2f2008-12-28 11:54:53 +00001487 if (vdel.len == 0 && table != NULL) {
Christian Heimes44720832008-05-26 13:01:01 +00001488 /* If no deletions are required, use faster code */
1489 for (i = inlen; --i >= 0; ) {
1490 c = Py_CHARMASK(*input++);
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001491 *output++ = table[c];
Christian Heimes44720832008-05-26 13:01:01 +00001492 }
Christian Heimes44720832008-05-26 13:01:01 +00001493 goto done;
1494 }
Georg Brandl6425a2f2008-12-28 11:54:53 +00001495
1496 if (table == NULL) {
1497 for (i = 0; i < 256; i++)
1498 trans_table[i] = Py_CHARMASK(i);
1499 } else {
1500 for (i = 0; i < 256; i++)
1501 trans_table[i] = Py_CHARMASK(table[i]);
1502 }
Christian Heimes44720832008-05-26 13:01:01 +00001503
1504 for (i = 0; i < vdel.len; i++)
1505 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1506
1507 for (i = inlen; --i >= 0; ) {
1508 c = Py_CHARMASK(*input++);
1509 if (trans_table[c] != -1)
1510 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1511 continue;
Christian Heimes44720832008-05-26 13:01:01 +00001512 }
1513 /* Fix the size of the resulting string */
1514 if (inlen > 0)
1515 PyByteArray_Resize(result, output - output_start);
1516
1517done:
Georg Brandl6425a2f2008-12-28 11:54:53 +00001518 if (tableobj != NULL)
1519 PyBuffer_Release(&vtable);
Christian Heimes44720832008-05-26 13:01:01 +00001520 if (delobj != NULL)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001521 PyBuffer_Release(&vdel);
Christian Heimes44720832008-05-26 13:01:01 +00001522 return result;
1523}
1524
1525
Christian Heimes44720832008-05-26 13:01:01 +00001526/* find and count characters and substrings */
1527
1528#define findchar(target, target_len, c) \
1529 ((char *)memchr((const void *)(target), c, target_len))
1530
Christian Heimes44720832008-05-26 13:01:01 +00001531
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001532/* Bytes ops must return a string, create a copy */
Christian Heimes44720832008-05-26 13:01:01 +00001533Py_LOCAL(PyByteArrayObject *)
1534return_self(PyByteArrayObject *self)
1535{
Christian Heimes44720832008-05-26 13:01:01 +00001536 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1537 PyByteArray_AS_STRING(self),
1538 PyByteArray_GET_SIZE(self));
1539}
1540
1541Py_LOCAL_INLINE(Py_ssize_t)
1542countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1543{
1544 Py_ssize_t count=0;
1545 const char *start=target;
1546 const char *end=target+target_len;
1547
1548 while ( (start=findchar(start, end-start, c)) != NULL ) {
1549 count++;
1550 if (count >= maxcount)
1551 break;
1552 start += 1;
1553 }
1554 return count;
1555}
1556
Christian Heimes44720832008-05-26 13:01:01 +00001557
1558/* Algorithms for different cases of string replacement */
1559
1560/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1561Py_LOCAL(PyByteArrayObject *)
1562replace_interleave(PyByteArrayObject *self,
1563 const char *to_s, Py_ssize_t to_len,
1564 Py_ssize_t maxcount)
1565{
1566 char *self_s, *result_s;
1567 Py_ssize_t self_len, result_len;
1568 Py_ssize_t count, i, product;
1569 PyByteArrayObject *result;
1570
1571 self_len = PyByteArray_GET_SIZE(self);
1572
1573 /* 1 at the end plus 1 after every character */
1574 count = self_len+1;
1575 if (maxcount < count)
1576 count = maxcount;
1577
1578 /* Check for overflow */
1579 /* result_len = count * to_len + self_len; */
1580 product = count * to_len;
1581 if (product / to_len != count) {
1582 PyErr_SetString(PyExc_OverflowError,
1583 "replace string is too long");
1584 return NULL;
1585 }
1586 result_len = product + self_len;
1587 if (result_len < 0) {
1588 PyErr_SetString(PyExc_OverflowError,
1589 "replace string is too long");
1590 return NULL;
1591 }
1592
1593 if (! (result = (PyByteArrayObject *)
1594 PyByteArray_FromStringAndSize(NULL, result_len)) )
1595 return NULL;
1596
1597 self_s = PyByteArray_AS_STRING(self);
1598 result_s = PyByteArray_AS_STRING(result);
1599
1600 /* TODO: special case single character, which doesn't need memcpy */
1601
1602 /* Lay the first one down (guaranteed this will occur) */
1603 Py_MEMCPY(result_s, to_s, to_len);
1604 result_s += to_len;
1605 count -= 1;
1606
1607 for (i=0; i<count; i++) {
1608 *result_s++ = *self_s++;
1609 Py_MEMCPY(result_s, to_s, to_len);
1610 result_s += to_len;
1611 }
1612
1613 /* Copy the rest of the original string */
1614 Py_MEMCPY(result_s, self_s, self_len-i);
1615
1616 return result;
1617}
1618
1619/* Special case for deleting a single character */
1620/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1621Py_LOCAL(PyByteArrayObject *)
1622replace_delete_single_character(PyByteArrayObject *self,
1623 char from_c, Py_ssize_t maxcount)
1624{
1625 char *self_s, *result_s;
1626 char *start, *next, *end;
1627 Py_ssize_t self_len, result_len;
1628 Py_ssize_t count;
1629 PyByteArrayObject *result;
1630
1631 self_len = PyByteArray_GET_SIZE(self);
1632 self_s = PyByteArray_AS_STRING(self);
1633
1634 count = countchar(self_s, self_len, from_c, maxcount);
1635 if (count == 0) {
1636 return return_self(self);
1637 }
1638
1639 result_len = self_len - count; /* from_len == 1 */
1640 assert(result_len>=0);
1641
1642 if ( (result = (PyByteArrayObject *)
1643 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1644 return NULL;
1645 result_s = PyByteArray_AS_STRING(result);
1646
1647 start = self_s;
1648 end = self_s + self_len;
1649 while (count-- > 0) {
1650 next = findchar(start, end-start, from_c);
1651 if (next == NULL)
1652 break;
1653 Py_MEMCPY(result_s, start, next-start);
1654 result_s += (next-start);
1655 start = next+1;
1656 }
1657 Py_MEMCPY(result_s, start, end-start);
1658
1659 return result;
1660}
1661
1662/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1663
1664Py_LOCAL(PyByteArrayObject *)
1665replace_delete_substring(PyByteArrayObject *self,
1666 const char *from_s, Py_ssize_t from_len,
1667 Py_ssize_t maxcount)
1668{
1669 char *self_s, *result_s;
1670 char *start, *next, *end;
1671 Py_ssize_t self_len, result_len;
1672 Py_ssize_t count, offset;
1673 PyByteArrayObject *result;
1674
1675 self_len = PyByteArray_GET_SIZE(self);
1676 self_s = PyByteArray_AS_STRING(self);
1677
Antoine Pitrou64672132010-01-13 07:55:48 +00001678 count = stringlib_count(self_s, self_len,
1679 from_s, from_len,
1680 maxcount);
Christian Heimes44720832008-05-26 13:01:01 +00001681
1682 if (count == 0) {
1683 /* no matches */
1684 return return_self(self);
1685 }
1686
1687 result_len = self_len - (count * from_len);
1688 assert (result_len>=0);
1689
1690 if ( (result = (PyByteArrayObject *)
1691 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1692 return NULL;
1693
1694 result_s = PyByteArray_AS_STRING(result);
1695
1696 start = self_s;
1697 end = self_s + self_len;
1698 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001699 offset = stringlib_find(start, end-start,
1700 from_s, from_len,
1701 0);
Christian Heimes44720832008-05-26 13:01:01 +00001702 if (offset == -1)
1703 break;
1704 next = start + offset;
1705
1706 Py_MEMCPY(result_s, start, next-start);
1707
1708 result_s += (next-start);
1709 start = next+from_len;
1710 }
1711 Py_MEMCPY(result_s, start, end-start);
1712 return result;
1713}
1714
1715/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1716Py_LOCAL(PyByteArrayObject *)
1717replace_single_character_in_place(PyByteArrayObject *self,
1718 char from_c, char to_c,
1719 Py_ssize_t maxcount)
1720{
1721 char *self_s, *result_s, *start, *end, *next;
1722 Py_ssize_t self_len;
1723 PyByteArrayObject *result;
1724
1725 /* The result string will be the same size */
1726 self_s = PyByteArray_AS_STRING(self);
1727 self_len = PyByteArray_GET_SIZE(self);
1728
1729 next = findchar(self_s, self_len, from_c);
1730
1731 if (next == NULL) {
1732 /* No matches; return the original bytes */
1733 return return_self(self);
1734 }
1735
1736 /* Need to make a new bytes */
1737 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1738 if (result == NULL)
1739 return NULL;
1740 result_s = PyByteArray_AS_STRING(result);
1741 Py_MEMCPY(result_s, self_s, self_len);
1742
1743 /* change everything in-place, starting with this one */
1744 start = result_s + (next-self_s);
1745 *start = to_c;
1746 start++;
1747 end = result_s + self_len;
1748
1749 while (--maxcount > 0) {
1750 next = findchar(start, end-start, from_c);
1751 if (next == NULL)
1752 break;
1753 *next = to_c;
1754 start = next+1;
1755 }
1756
1757 return result;
1758}
1759
1760/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1761Py_LOCAL(PyByteArrayObject *)
1762replace_substring_in_place(PyByteArrayObject *self,
1763 const char *from_s, Py_ssize_t from_len,
1764 const char *to_s, Py_ssize_t to_len,
1765 Py_ssize_t maxcount)
1766{
1767 char *result_s, *start, *end;
1768 char *self_s;
1769 Py_ssize_t self_len, offset;
1770 PyByteArrayObject *result;
1771
1772 /* The result bytes will be the same size */
1773
1774 self_s = PyByteArray_AS_STRING(self);
1775 self_len = PyByteArray_GET_SIZE(self);
1776
Antoine Pitrou64672132010-01-13 07:55:48 +00001777 offset = stringlib_find(self_s, self_len,
1778 from_s, from_len,
1779 0);
Christian Heimes44720832008-05-26 13:01:01 +00001780 if (offset == -1) {
1781 /* No matches; return the original bytes */
1782 return return_self(self);
1783 }
1784
1785 /* Need to make a new bytes */
1786 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1787 if (result == NULL)
1788 return NULL;
1789 result_s = PyByteArray_AS_STRING(result);
1790 Py_MEMCPY(result_s, self_s, self_len);
1791
1792 /* change everything in-place, starting with this one */
1793 start = result_s + offset;
1794 Py_MEMCPY(start, to_s, from_len);
1795 start += from_len;
1796 end = result_s + self_len;
1797
1798 while ( --maxcount > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001799 offset = stringlib_find(start, end-start,
1800 from_s, from_len,
1801 0);
Christian Heimes44720832008-05-26 13:01:01 +00001802 if (offset==-1)
1803 break;
1804 Py_MEMCPY(start+offset, to_s, from_len);
1805 start += offset+from_len;
1806 }
1807
1808 return result;
1809}
1810
1811/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1812Py_LOCAL(PyByteArrayObject *)
1813replace_single_character(PyByteArrayObject *self,
1814 char from_c,
1815 const char *to_s, Py_ssize_t to_len,
1816 Py_ssize_t maxcount)
1817{
1818 char *self_s, *result_s;
1819 char *start, *next, *end;
1820 Py_ssize_t self_len, result_len;
1821 Py_ssize_t count, product;
1822 PyByteArrayObject *result;
1823
1824 self_s = PyByteArray_AS_STRING(self);
1825 self_len = PyByteArray_GET_SIZE(self);
1826
1827 count = countchar(self_s, self_len, from_c, maxcount);
1828 if (count == 0) {
1829 /* no matches, return unchanged */
1830 return return_self(self);
1831 }
1832
1833 /* use the difference between current and new, hence the "-1" */
1834 /* result_len = self_len + count * (to_len-1) */
1835 product = count * (to_len-1);
1836 if (product / (to_len-1) != count) {
1837 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1838 return NULL;
1839 }
1840 result_len = self_len + product;
1841 if (result_len < 0) {
1842 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1843 return NULL;
1844 }
1845
1846 if ( (result = (PyByteArrayObject *)
1847 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1848 return NULL;
1849 result_s = PyByteArray_AS_STRING(result);
1850
1851 start = self_s;
1852 end = self_s + self_len;
1853 while (count-- > 0) {
1854 next = findchar(start, end-start, from_c);
1855 if (next == NULL)
1856 break;
1857
1858 if (next == start) {
1859 /* replace with the 'to' */
1860 Py_MEMCPY(result_s, to_s, to_len);
1861 result_s += to_len;
1862 start += 1;
1863 } else {
1864 /* copy the unchanged old then the 'to' */
1865 Py_MEMCPY(result_s, start, next-start);
1866 result_s += (next-start);
1867 Py_MEMCPY(result_s, to_s, to_len);
1868 result_s += to_len;
1869 start = next+1;
1870 }
1871 }
1872 /* Copy the remainder of the remaining bytes */
1873 Py_MEMCPY(result_s, start, end-start);
1874
1875 return result;
1876}
1877
1878/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1879Py_LOCAL(PyByteArrayObject *)
1880replace_substring(PyByteArrayObject *self,
1881 const char *from_s, Py_ssize_t from_len,
1882 const char *to_s, Py_ssize_t to_len,
1883 Py_ssize_t maxcount)
1884{
1885 char *self_s, *result_s;
1886 char *start, *next, *end;
1887 Py_ssize_t self_len, result_len;
1888 Py_ssize_t count, offset, product;
1889 PyByteArrayObject *result;
1890
1891 self_s = PyByteArray_AS_STRING(self);
1892 self_len = PyByteArray_GET_SIZE(self);
1893
Antoine Pitrou64672132010-01-13 07:55:48 +00001894 count = stringlib_count(self_s, self_len,
1895 from_s, from_len,
1896 maxcount);
1897
Christian Heimes44720832008-05-26 13:01:01 +00001898 if (count == 0) {
1899 /* no matches, return unchanged */
1900 return return_self(self);
1901 }
1902
1903 /* Check for overflow */
1904 /* result_len = self_len + count * (to_len-from_len) */
1905 product = count * (to_len-from_len);
1906 if (product / (to_len-from_len) != count) {
1907 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1908 return NULL;
1909 }
1910 result_len = self_len + product;
1911 if (result_len < 0) {
1912 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1913 return NULL;
1914 }
1915
1916 if ( (result = (PyByteArrayObject *)
1917 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1918 return NULL;
1919 result_s = PyByteArray_AS_STRING(result);
1920
1921 start = self_s;
1922 end = self_s + self_len;
1923 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001924 offset = stringlib_find(start, end-start,
1925 from_s, from_len,
1926 0);
Christian Heimes44720832008-05-26 13:01:01 +00001927 if (offset == -1)
1928 break;
1929 next = start+offset;
1930 if (next == start) {
1931 /* replace with the 'to' */
1932 Py_MEMCPY(result_s, to_s, to_len);
1933 result_s += to_len;
1934 start += from_len;
1935 } else {
1936 /* copy the unchanged old then the 'to' */
1937 Py_MEMCPY(result_s, start, next-start);
1938 result_s += (next-start);
1939 Py_MEMCPY(result_s, to_s, to_len);
1940 result_s += to_len;
1941 start = next+from_len;
1942 }
1943 }
1944 /* Copy the remainder of the remaining bytes */
1945 Py_MEMCPY(result_s, start, end-start);
1946
1947 return result;
1948}
1949
1950
1951Py_LOCAL(PyByteArrayObject *)
1952replace(PyByteArrayObject *self,
1953 const char *from_s, Py_ssize_t from_len,
1954 const char *to_s, Py_ssize_t to_len,
1955 Py_ssize_t maxcount)
1956{
1957 if (maxcount < 0) {
1958 maxcount = PY_SSIZE_T_MAX;
1959 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1960 /* nothing to do; return the original bytes */
1961 return return_self(self);
1962 }
1963
1964 if (maxcount == 0 ||
1965 (from_len == 0 && to_len == 0)) {
1966 /* nothing to do; return the original bytes */
1967 return return_self(self);
1968 }
1969
1970 /* Handle zero-length special cases */
1971
1972 if (from_len == 0) {
1973 /* insert the 'to' bytes everywhere. */
1974 /* >>> "Python".replace("", ".") */
1975 /* '.P.y.t.h.o.n.' */
1976 return replace_interleave(self, to_s, to_len, maxcount);
1977 }
1978
1979 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1980 /* point for an empty self bytes to generate a non-empty bytes */
1981 /* Special case so the remaining code always gets a non-empty bytes */
1982 if (PyByteArray_GET_SIZE(self) == 0) {
1983 return return_self(self);
1984 }
1985
1986 if (to_len == 0) {
1987 /* delete all occurances of 'from' bytes */
1988 if (from_len == 1) {
1989 return replace_delete_single_character(
1990 self, from_s[0], maxcount);
1991 } else {
1992 return replace_delete_substring(self, from_s, from_len, maxcount);
1993 }
1994 }
1995
1996 /* Handle special case where both bytes have the same length */
1997
1998 if (from_len == to_len) {
1999 if (from_len == 1) {
2000 return replace_single_character_in_place(
2001 self,
2002 from_s[0],
2003 to_s[0],
2004 maxcount);
2005 } else {
2006 return replace_substring_in_place(
2007 self, from_s, from_len, to_s, to_len, maxcount);
2008 }
2009 }
2010
2011 /* Otherwise use the more generic algorithms */
2012 if (from_len == 1) {
2013 return replace_single_character(self, from_s[0],
2014 to_s, to_len, maxcount);
2015 } else {
2016 /* len('from')>=2, len('to')>=1 */
2017 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2018 }
2019}
2020
2021
2022PyDoc_STRVAR(replace__doc__,
2023"B.replace(old, new[, count]) -> bytes\n\
2024\n\
2025Return a copy of B with all occurrences of subsection\n\
2026old replaced by new. If the optional argument count is\n\
2027given, only the first count occurrences are replaced.");
2028
2029static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002030bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002031{
2032 Py_ssize_t count = -1;
2033 PyObject *from, *to, *res;
2034 Py_buffer vfrom, vto;
2035
2036 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2037 return NULL;
2038
2039 if (_getbuffer(from, &vfrom) < 0)
2040 return NULL;
2041 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002042 PyBuffer_Release(&vfrom);
Christian Heimes44720832008-05-26 13:01:01 +00002043 return NULL;
2044 }
2045
2046 res = (PyObject *)replace((PyByteArrayObject *) self,
2047 vfrom.buf, vfrom.len,
2048 vto.buf, vto.len, count);
2049
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002050 PyBuffer_Release(&vfrom);
2051 PyBuffer_Release(&vto);
Christian Heimes44720832008-05-26 13:01:01 +00002052 return res;
2053}
2054
Christian Heimes44720832008-05-26 13:01:01 +00002055PyDoc_STRVAR(split__doc__,
2056"B.split([sep[, maxsplit]]) -> list of bytearray\n\
2057\n\
2058Return a list of the sections in B, using sep as the delimiter.\n\
2059If sep is not given, B is split on ASCII whitespace characters\n\
2060(space, tab, return, newline, formfeed, vertical tab).\n\
2061If maxsplit is given, at most maxsplit splits are done.");
2062
2063static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002064bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002065{
Antoine Pitrou64672132010-01-13 07:55:48 +00002066 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2067 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002068 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002069 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002070 Py_buffer vsub;
Christian Heimes44720832008-05-26 13:01:01 +00002071
2072 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2073 return NULL;
2074 if (maxsplit < 0)
2075 maxsplit = PY_SSIZE_T_MAX;
2076
2077 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002078 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002079
2080 if (_getbuffer(subobj, &vsub) < 0)
2081 return NULL;
2082 sub = vsub.buf;
2083 n = vsub.len;
2084
Antoine Pitrou64672132010-01-13 07:55:48 +00002085 list = stringlib_split(
2086 (PyObject*) self, s, len, sub, n, maxsplit
2087 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002088 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002089 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002090}
2091
2092PyDoc_STRVAR(partition__doc__,
2093"B.partition(sep) -> (head, sep, tail)\n\
2094\n\
2095Searches for the separator sep in B, and returns the part before it,\n\
2096the separator itself, and the part after it. If the separator is not\n\
2097found, returns B and two empty bytearray objects.");
2098
2099static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002100bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002101{
2102 PyObject *bytesep, *result;
2103
2104 bytesep = PyByteArray_FromObject(sep_obj);
2105 if (! bytesep)
2106 return NULL;
2107
2108 result = stringlib_partition(
2109 (PyObject*) self,
2110 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2111 bytesep,
2112 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2113 );
2114
2115 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002116 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002117}
2118
2119PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti1fafaab2010-01-25 11:24:37 +00002120"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes44720832008-05-26 13:01:01 +00002121\n\
2122Searches for the separator sep in B, starting at the end of B,\n\
2123and returns the part before it, the separator itself, and the\n\
2124part after it. If the separator is not found, returns two empty\n\
2125bytearray objects and B.");
2126
2127static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002128bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002129{
2130 PyObject *bytesep, *result;
2131
2132 bytesep = PyByteArray_FromObject(sep_obj);
2133 if (! bytesep)
2134 return NULL;
2135
2136 result = stringlib_rpartition(
2137 (PyObject*) self,
2138 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2139 bytesep,
2140 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2141 );
2142
2143 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002144 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002145}
2146
2147PyDoc_STRVAR(rsplit__doc__,
2148"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2149\n\
2150Return a list of the sections in B, using sep as the delimiter,\n\
2151starting at the end of B and working to the front.\n\
2152If sep is not given, B is split on ASCII whitespace characters\n\
2153(space, tab, return, newline, formfeed, vertical tab).\n\
2154If maxsplit is given, at most maxsplit splits are done.");
2155
2156static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002157bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002158{
Antoine Pitrou64672132010-01-13 07:55:48 +00002159 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2160 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002161 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002162 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002163 Py_buffer vsub;
2164
2165 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2166 return NULL;
2167 if (maxsplit < 0)
2168 maxsplit = PY_SSIZE_T_MAX;
2169
2170 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002171 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002172
2173 if (_getbuffer(subobj, &vsub) < 0)
2174 return NULL;
2175 sub = vsub.buf;
2176 n = vsub.len;
2177
Antoine Pitrou64672132010-01-13 07:55:48 +00002178 list = stringlib_rsplit(
2179 (PyObject*) self, s, len, sub, n, maxsplit
2180 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002181 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002182 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002183}
2184
2185PyDoc_STRVAR(reverse__doc__,
2186"B.reverse() -> None\n\
2187\n\
2188Reverse the order of the values in B in place.");
2189static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002190bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes44720832008-05-26 13:01:01 +00002191{
2192 char swap, *head, *tail;
2193 Py_ssize_t i, j, n = Py_SIZE(self);
2194
2195 j = n / 2;
2196 head = self->ob_bytes;
2197 tail = head + n - 1;
2198 for (i = 0; i < j; i++) {
2199 swap = *head;
2200 *head++ = *tail;
2201 *tail-- = swap;
2202 }
2203
2204 Py_RETURN_NONE;
2205}
2206
2207PyDoc_STRVAR(insert__doc__,
2208"B.insert(index, int) -> None\n\
2209\n\
2210Insert a single item into the bytearray before the given index.");
2211static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002212bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002213{
Georg Brandl3e483f62008-07-16 22:57:41 +00002214 PyObject *value;
2215 int ival;
Christian Heimes44720832008-05-26 13:01:01 +00002216 Py_ssize_t where, n = Py_SIZE(self);
2217
Georg Brandl3e483f62008-07-16 22:57:41 +00002218 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes44720832008-05-26 13:01:01 +00002219 return NULL;
2220
2221 if (n == PY_SSIZE_T_MAX) {
2222 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002223 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002224 return NULL;
2225 }
Georg Brandl3e483f62008-07-16 22:57:41 +00002226 if (!_getbytevalue(value, &ival))
Christian Heimes44720832008-05-26 13:01:01 +00002227 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002228 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2229 return NULL;
2230
2231 if (where < 0) {
2232 where += n;
2233 if (where < 0)
2234 where = 0;
2235 }
2236 if (where > n)
2237 where = n;
2238 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl3e483f62008-07-16 22:57:41 +00002239 self->ob_bytes[where] = ival;
Christian Heimes44720832008-05-26 13:01:01 +00002240
2241 Py_RETURN_NONE;
2242}
2243
2244PyDoc_STRVAR(append__doc__,
2245"B.append(int) -> None\n\
2246\n\
2247Append a single item to the end of B.");
2248static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002249bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002250{
2251 int value;
2252 Py_ssize_t n = Py_SIZE(self);
2253
2254 if (! _getbytevalue(arg, &value))
2255 return NULL;
2256 if (n == PY_SSIZE_T_MAX) {
2257 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002258 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002259 return NULL;
2260 }
2261 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2262 return NULL;
2263
2264 self->ob_bytes[n] = value;
2265
2266 Py_RETURN_NONE;
2267}
2268
2269PyDoc_STRVAR(extend__doc__,
2270"B.extend(iterable int) -> None\n\
2271\n\
2272Append all the elements from the iterator or sequence to the\n\
2273end of B.");
2274static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002275bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002276{
Benjamin Petersond6720012009-04-18 15:31:34 +00002277 PyObject *it, *item, *bytearray_obj;
Christian Heimes44720832008-05-26 13:01:01 +00002278 Py_ssize_t buf_size = 0, len = 0;
2279 int value;
2280 char *buf;
2281
Benjamin Petersond6720012009-04-18 15:31:34 +00002282 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes44720832008-05-26 13:01:01 +00002283 if (PyObject_CheckBuffer(arg)) {
Benjamin Petersond6720012009-04-18 15:31:34 +00002284 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002285 return NULL;
2286
2287 Py_RETURN_NONE;
2288 }
2289
2290 it = PyObject_GetIter(arg);
2291 if (it == NULL)
2292 return NULL;
2293
2294 /* Try to determine the length of the argument. 32 is abitrary. */
2295 buf_size = _PyObject_LengthHint(arg, 32);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002296 if (buf_size == -1) {
2297 Py_DECREF(it);
2298 return NULL;
2299 }
Christian Heimes44720832008-05-26 13:01:01 +00002300
Benjamin Petersond6720012009-04-18 15:31:34 +00002301 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2302 if (bytearray_obj == NULL)
Christian Heimes44720832008-05-26 13:01:01 +00002303 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002304 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002305
2306 while ((item = PyIter_Next(it)) != NULL) {
2307 if (! _getbytevalue(item, &value)) {
2308 Py_DECREF(item);
2309 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002310 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002311 return NULL;
2312 }
2313 buf[len++] = value;
2314 Py_DECREF(item);
2315
2316 if (len >= buf_size) {
2317 buf_size = len + (len >> 1) + 1;
Benjamin Petersond6720012009-04-18 15:31:34 +00002318 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00002319 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002320 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002321 return NULL;
2322 }
2323 /* Recompute the `buf' pointer, since the resizing operation may
2324 have invalidated it. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002325 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002326 }
2327 }
2328 Py_DECREF(it);
2329
2330 /* Resize down to exact size. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002331 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2332 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002333 return NULL;
2334 }
2335
Benjamin Petersond6720012009-04-18 15:31:34 +00002336 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002337 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002338 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002339
2340 Py_RETURN_NONE;
2341}
2342
2343PyDoc_STRVAR(pop__doc__,
2344"B.pop([index]) -> int\n\
2345\n\
2346Remove and return a single item from B. If no index\n\
Andrew M. Kuchlingd8972642008-06-21 13:29:12 +00002347argument is given, will pop the last value.");
Christian Heimes44720832008-05-26 13:01:01 +00002348static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002349bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002350{
2351 int value;
2352 Py_ssize_t where = -1, n = Py_SIZE(self);
2353
2354 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2355 return NULL;
2356
2357 if (n == 0) {
2358 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002359 "cannot pop an empty bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002360 return NULL;
2361 }
2362 if (where < 0)
2363 where += Py_SIZE(self);
2364 if (where < 0 || where >= Py_SIZE(self)) {
2365 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2366 return NULL;
2367 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002368 if (!_canresize(self))
2369 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002370
2371 value = self->ob_bytes[where];
2372 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2373 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2374 return NULL;
2375
Mark Dickinsonc8a7c7c2009-09-06 10:03:31 +00002376 return PyInt_FromLong((unsigned char)value);
Christian Heimes44720832008-05-26 13:01:01 +00002377}
2378
2379PyDoc_STRVAR(remove__doc__,
2380"B.remove(int) -> None\n\
2381\n\
2382Remove the first occurance of a value in B.");
2383static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002384bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002385{
2386 int value;
2387 Py_ssize_t where, n = Py_SIZE(self);
2388
2389 if (! _getbytevalue(arg, &value))
2390 return NULL;
2391
2392 for (where = 0; where < n; where++) {
2393 if (self->ob_bytes[where] == value)
2394 break;
2395 }
2396 if (where == n) {
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002397 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002398 return NULL;
2399 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002400 if (!_canresize(self))
2401 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002402
2403 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2404 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2405 return NULL;
2406
2407 Py_RETURN_NONE;
2408}
2409
2410/* XXX These two helpers could be optimized if argsize == 1 */
2411
2412static Py_ssize_t
2413lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2414 void *argptr, Py_ssize_t argsize)
2415{
2416 Py_ssize_t i = 0;
2417 while (i < mysize && memchr(argptr, myptr[i], argsize))
2418 i++;
2419 return i;
2420}
2421
2422static Py_ssize_t
2423rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2424 void *argptr, Py_ssize_t argsize)
2425{
2426 Py_ssize_t i = mysize - 1;
2427 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2428 i--;
2429 return i + 1;
2430}
2431
2432PyDoc_STRVAR(strip__doc__,
2433"B.strip([bytes]) -> bytearray\n\
2434\n\
2435Strip leading and trailing bytes contained in the argument.\n\
2436If the argument is omitted, strip ASCII whitespace.");
2437static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002438bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002439{
2440 Py_ssize_t left, right, mysize, argsize;
2441 void *myptr, *argptr;
2442 PyObject *arg = Py_None;
2443 Py_buffer varg;
2444 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2445 return NULL;
2446 if (arg == Py_None) {
2447 argptr = "\t\n\r\f\v ";
2448 argsize = 6;
2449 }
2450 else {
2451 if (_getbuffer(arg, &varg) < 0)
2452 return NULL;
2453 argptr = varg.buf;
2454 argsize = varg.len;
2455 }
2456 myptr = self->ob_bytes;
2457 mysize = Py_SIZE(self);
2458 left = lstrip_helper(myptr, mysize, argptr, argsize);
2459 if (left == mysize)
2460 right = left;
2461 else
2462 right = rstrip_helper(myptr, mysize, argptr, argsize);
2463 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002464 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002465 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2466}
2467
2468PyDoc_STRVAR(lstrip__doc__,
2469"B.lstrip([bytes]) -> bytearray\n\
2470\n\
2471Strip leading bytes contained in the argument.\n\
2472If the argument is omitted, strip leading ASCII whitespace.");
2473static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002474bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002475{
2476 Py_ssize_t left, right, mysize, argsize;
2477 void *myptr, *argptr;
2478 PyObject *arg = Py_None;
2479 Py_buffer varg;
2480 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2481 return NULL;
2482 if (arg == Py_None) {
2483 argptr = "\t\n\r\f\v ";
2484 argsize = 6;
2485 }
2486 else {
2487 if (_getbuffer(arg, &varg) < 0)
2488 return NULL;
2489 argptr = varg.buf;
2490 argsize = varg.len;
2491 }
2492 myptr = self->ob_bytes;
2493 mysize = Py_SIZE(self);
2494 left = lstrip_helper(myptr, mysize, argptr, argsize);
2495 right = mysize;
2496 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002497 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002498 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2499}
2500
2501PyDoc_STRVAR(rstrip__doc__,
2502"B.rstrip([bytes]) -> bytearray\n\
2503\n\
2504Strip trailing bytes contained in the argument.\n\
2505If the argument is omitted, strip trailing ASCII whitespace.");
2506static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002507bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002508{
2509 Py_ssize_t left, right, mysize, argsize;
2510 void *myptr, *argptr;
2511 PyObject *arg = Py_None;
2512 Py_buffer varg;
2513 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2514 return NULL;
2515 if (arg == Py_None) {
2516 argptr = "\t\n\r\f\v ";
2517 argsize = 6;
2518 }
2519 else {
2520 if (_getbuffer(arg, &varg) < 0)
2521 return NULL;
2522 argptr = varg.buf;
2523 argsize = varg.len;
2524 }
2525 myptr = self->ob_bytes;
2526 mysize = Py_SIZE(self);
2527 left = 0;
2528 right = rstrip_helper(myptr, mysize, argptr, argsize);
2529 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002530 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002531 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2532}
2533
2534PyDoc_STRVAR(decode_doc,
2535"B.decode([encoding[, errors]]) -> unicode object.\n\
2536\n\
2537Decodes B using the codec registered for encoding. encoding defaults\n\
2538to the default encoding. errors may be given to set a different error\n\
2539handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2540a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2541as well as any other name registered with codecs.register_error that is\n\
2542able to handle UnicodeDecodeErrors.");
2543
2544static PyObject *
Benjamin Petersondc782b52009-09-18 21:46:21 +00002545bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes44720832008-05-26 13:01:01 +00002546{
2547 const char *encoding = NULL;
2548 const char *errors = NULL;
Benjamin Petersondc782b52009-09-18 21:46:21 +00002549 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes44720832008-05-26 13:01:01 +00002550
Benjamin Petersondc782b52009-09-18 21:46:21 +00002551 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes44720832008-05-26 13:01:01 +00002552 return NULL;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002553 if (encoding == NULL) {
2554#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002555 encoding = PyUnicode_GetDefaultEncoding();
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002556#else
2557 PyErr_SetString(PyExc_ValueError, "no encoding specified");
2558 return NULL;
2559#endif
2560 }
Christian Heimes44720832008-05-26 13:01:01 +00002561 return PyCodec_Decode(self, encoding, errors);
2562}
2563
2564PyDoc_STRVAR(alloc_doc,
2565"B.__alloc__() -> int\n\
2566\n\
2567Returns the number of bytes actually allocated.");
2568
2569static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002570bytearray_alloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002571{
2572 return PyInt_FromSsize_t(self->ob_alloc);
2573}
2574
2575PyDoc_STRVAR(join_doc,
2576"B.join(iterable_of_bytes) -> bytes\n\
2577\n\
2578Concatenates any number of bytearray objects, with B in between each pair.");
2579
2580static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002581bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002582{
2583 PyObject *seq;
2584 Py_ssize_t mysize = Py_SIZE(self);
2585 Py_ssize_t i;
2586 Py_ssize_t n;
2587 PyObject **items;
2588 Py_ssize_t totalsize = 0;
2589 PyObject *result;
2590 char *dest;
2591
2592 seq = PySequence_Fast(it, "can only join an iterable");
2593 if (seq == NULL)
2594 return NULL;
2595 n = PySequence_Fast_GET_SIZE(seq);
2596 items = PySequence_Fast_ITEMS(seq);
2597
2598 /* Compute the total size, and check that they are all bytes */
2599 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2600 for (i = 0; i < n; i++) {
2601 PyObject *obj = items[i];
2602 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2603 PyErr_Format(PyExc_TypeError,
2604 "can only join an iterable of bytes "
2605 "(item %ld has type '%.100s')",
2606 /* XXX %ld isn't right on Win64 */
2607 (long)i, Py_TYPE(obj)->tp_name);
2608 goto error;
2609 }
2610 if (i > 0)
2611 totalsize += mysize;
2612 totalsize += Py_SIZE(obj);
2613 if (totalsize < 0) {
2614 PyErr_NoMemory();
2615 goto error;
2616 }
2617 }
2618
2619 /* Allocate the result, and copy the bytes */
2620 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2621 if (result == NULL)
2622 goto error;
2623 dest = PyByteArray_AS_STRING(result);
2624 for (i = 0; i < n; i++) {
2625 PyObject *obj = items[i];
2626 Py_ssize_t size = Py_SIZE(obj);
2627 char *buf;
2628 if (PyByteArray_Check(obj))
2629 buf = PyByteArray_AS_STRING(obj);
2630 else
2631 buf = PyBytes_AS_STRING(obj);
2632 if (i) {
2633 memcpy(dest, self->ob_bytes, mysize);
2634 dest += mysize;
2635 }
2636 memcpy(dest, buf, size);
2637 dest += size;
2638 }
2639
2640 /* Done */
2641 Py_DECREF(seq);
2642 return result;
2643
2644 /* Error handling */
2645 error:
2646 Py_DECREF(seq);
2647 return NULL;
2648}
2649
Antoine Pitrou64672132010-01-13 07:55:48 +00002650PyDoc_STRVAR(splitlines__doc__,
2651"B.splitlines([keepends]) -> list of lines\n\
2652\n\
2653Return a list of the lines in B, breaking at line boundaries.\n\
2654Line breaks are not included in the resulting list unless keepends\n\
2655is given and true.");
2656
2657static PyObject*
2658bytearray_splitlines(PyObject *self, PyObject *args)
2659{
2660 int keepends = 0;
2661
2662 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2663 return NULL;
2664
2665 return stringlib_splitlines(
2666 (PyObject*) self, PyByteArray_AS_STRING(self),
2667 PyByteArray_GET_SIZE(self), keepends
2668 );
2669}
2670
Christian Heimes44720832008-05-26 13:01:01 +00002671PyDoc_STRVAR(fromhex_doc,
2672"bytearray.fromhex(string) -> bytearray\n\
2673\n\
2674Create a bytearray object from a string of hexadecimal numbers.\n\
2675Spaces between two numbers are accepted.\n\
2676Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2677
2678static int
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002679hex_digit_to_int(char c)
Christian Heimes44720832008-05-26 13:01:01 +00002680{
Eric Smithcac7af62009-04-27 19:04:37 +00002681 if (Py_ISDIGIT(c))
Christian Heimes44720832008-05-26 13:01:01 +00002682 return c - '0';
2683 else {
Eric Smithcac7af62009-04-27 19:04:37 +00002684 if (Py_ISUPPER(c))
2685 c = Py_TOLOWER(c);
Christian Heimes44720832008-05-26 13:01:01 +00002686 if (c >= 'a' && c <= 'f')
2687 return c - 'a' + 10;
2688 }
2689 return -1;
2690}
2691
2692static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002693bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002694{
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002695 PyObject *newbytes;
Christian Heimes44720832008-05-26 13:01:01 +00002696 char *buf;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002697 char *hex;
Christian Heimes44720832008-05-26 13:01:01 +00002698 Py_ssize_t hexlen, byteslen, i, j;
2699 int top, bot;
2700
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002701 if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
Christian Heimes44720832008-05-26 13:01:01 +00002702 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002703 byteslen = hexlen/2; /* This overestimates if there are spaces */
2704 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2705 if (!newbytes)
2706 return NULL;
2707 buf = PyByteArray_AS_STRING(newbytes);
2708 for (i = j = 0; i < hexlen; i += 2) {
2709 /* skip over spaces in the input */
2710 while (hex[i] == ' ')
2711 i++;
2712 if (i >= hexlen)
2713 break;
2714 top = hex_digit_to_int(hex[i]);
2715 bot = hex_digit_to_int(hex[i+1]);
2716 if (top == -1 || bot == -1) {
2717 PyErr_Format(PyExc_ValueError,
2718 "non-hexadecimal number found in "
2719 "fromhex() arg at position %zd", i);
2720 goto error;
2721 }
2722 buf[j++] = (top << 4) + bot;
2723 }
2724 if (PyByteArray_Resize(newbytes, j) < 0)
2725 goto error;
2726 return newbytes;
2727
2728 error:
2729 Py_DECREF(newbytes);
2730 return NULL;
2731}
2732
2733PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2734
2735static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002736bytearray_reduce(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002737{
2738 PyObject *latin1, *dict;
2739 if (self->ob_bytes)
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002740#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002741 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2742 Py_SIZE(self), NULL);
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002743#else
Mark Dickinson9d109742009-10-15 15:18:55 +00002744 latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002745#endif
Christian Heimes44720832008-05-26 13:01:01 +00002746 else
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002747#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002748 latin1 = PyUnicode_FromString("");
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002749#else
2750 latin1 = PyString_FromString("");
2751#endif
Christian Heimes44720832008-05-26 13:01:01 +00002752
2753 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2754 if (dict == NULL) {
2755 PyErr_Clear();
2756 dict = Py_None;
2757 Py_INCREF(dict);
2758 }
2759
2760 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2761}
2762
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002763PyDoc_STRVAR(sizeof_doc,
2764"B.__sizeof__() -> int\n\
2765 \n\
2766Returns the size of B in memory, in bytes");
2767static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002768bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002769{
Georg Brandl517cfdc2009-04-05 13:16:35 +00002770 Py_ssize_t res;
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002771
Georg Brandl517cfdc2009-04-05 13:16:35 +00002772 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2773 return PyInt_FromSsize_t(res);
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002774}
2775
Benjamin Petersond6720012009-04-18 15:31:34 +00002776static PySequenceMethods bytearray_as_sequence = {
2777 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes44720832008-05-26 13:01:01 +00002778 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Petersond6720012009-04-18 15:31:34 +00002779 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2780 (ssizeargfunc)bytearray_getitem, /* sq_item */
2781 0, /* sq_slice */
2782 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2783 0, /* sq_ass_slice */
2784 (objobjproc)bytearray_contains, /* sq_contains */
2785 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2786 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes44720832008-05-26 13:01:01 +00002787};
2788
Benjamin Petersond6720012009-04-18 15:31:34 +00002789static PyMappingMethods bytearray_as_mapping = {
2790 (lenfunc)bytearray_length,
2791 (binaryfunc)bytearray_subscript,
2792 (objobjargproc)bytearray_ass_subscript,
Christian Heimes44720832008-05-26 13:01:01 +00002793};
2794
Benjamin Petersond6720012009-04-18 15:31:34 +00002795static PyBufferProcs bytearray_as_buffer = {
2796 (readbufferproc)bytearray_buffer_getreadbuf,
2797 (writebufferproc)bytearray_buffer_getwritebuf,
2798 (segcountproc)bytearray_buffer_getsegcount,
2799 (charbufferproc)bytearray_buffer_getcharbuf,
2800 (getbufferproc)bytearray_getbuffer,
2801 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes44720832008-05-26 13:01:01 +00002802};
2803
2804static PyMethodDef
Benjamin Petersond6720012009-04-18 15:31:34 +00002805bytearray_methods[] = {
2806 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2807 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2808 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2809 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002810 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2811 _Py_capitalize__doc__},
2812 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002813 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Petersondc782b52009-09-18 21:46:21 +00002814 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002815 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002816 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2817 expandtabs__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002818 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2819 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2820 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes44720832008-05-26 13:01:01 +00002821 fromhex_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002822 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2823 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002824 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2825 _Py_isalnum__doc__},
2826 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2827 _Py_isalpha__doc__},
2828 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2829 _Py_isdigit__doc__},
2830 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2831 _Py_islower__doc__},
2832 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2833 _Py_isspace__doc__},
2834 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2835 _Py_istitle__doc__},
2836 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2837 _Py_isupper__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002838 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes44720832008-05-26 13:01:01 +00002839 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2840 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002841 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2842 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2843 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2844 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2845 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2846 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2847 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2848 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002849 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002850 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2851 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2852 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2853 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrou64672132010-01-13 07:55:48 +00002854 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002855 splitlines__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002856 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes44720832008-05-26 13:01:01 +00002857 startswith__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002858 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002859 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2860 _Py_swapcase__doc__},
2861 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002862 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002863 translate__doc__},
2864 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2865 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2866 {NULL}
2867};
2868
Benjamin Petersond6720012009-04-18 15:31:34 +00002869PyDoc_STRVAR(bytearray_doc,
Christian Heimes44720832008-05-26 13:01:01 +00002870"bytearray(iterable_of_ints) -> bytearray.\n\
2871bytearray(string, encoding[, errors]) -> bytearray.\n\
2872bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
2873bytearray(memory_view) -> bytearray.\n\
2874\n\
2875Construct an mutable bytearray object from:\n\
2876 - an iterable yielding integers in range(256)\n\
2877 - a text string encoded using the specified encoding\n\
2878 - a bytes or a bytearray object\n\
2879 - any object implementing the buffer API.\n\
2880\n\
2881bytearray(int) -> bytearray.\n\
2882\n\
2883Construct a zero-initialized bytearray of the given length.");
2884
2885
Benjamin Petersond6720012009-04-18 15:31:34 +00002886static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes44720832008-05-26 13:01:01 +00002887
2888PyTypeObject PyByteArray_Type = {
2889 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2890 "bytearray",
2891 sizeof(PyByteArrayObject),
2892 0,
Benjamin Petersond6720012009-04-18 15:31:34 +00002893 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00002894 0, /* tp_print */
2895 0, /* tp_getattr */
2896 0, /* tp_setattr */
2897 0, /* tp_compare */
Benjamin Petersond6720012009-04-18 15:31:34 +00002898 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes44720832008-05-26 13:01:01 +00002899 0, /* tp_as_number */
Benjamin Petersond6720012009-04-18 15:31:34 +00002900 &bytearray_as_sequence, /* tp_as_sequence */
2901 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes44720832008-05-26 13:01:01 +00002902 0, /* tp_hash */
2903 0, /* tp_call */
Benjamin Petersond6720012009-04-18 15:31:34 +00002904 bytearray_str, /* tp_str */
Christian Heimes44720832008-05-26 13:01:01 +00002905 PyObject_GenericGetAttr, /* tp_getattro */
2906 0, /* tp_setattro */
Benjamin Petersond6720012009-04-18 15:31:34 +00002907 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes44720832008-05-26 13:01:01 +00002908 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2909 Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
Benjamin Petersond6720012009-04-18 15:31:34 +00002910 bytearray_doc, /* tp_doc */
Christian Heimes44720832008-05-26 13:01:01 +00002911 0, /* tp_traverse */
2912 0, /* tp_clear */
Benjamin Petersond6720012009-04-18 15:31:34 +00002913 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes44720832008-05-26 13:01:01 +00002914 0, /* tp_weaklistoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002915 bytearray_iter, /* tp_iter */
Christian Heimes44720832008-05-26 13:01:01 +00002916 0, /* tp_iternext */
Benjamin Petersond6720012009-04-18 15:31:34 +00002917 bytearray_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00002918 0, /* tp_members */
2919 0, /* tp_getset */
2920 0, /* tp_base */
2921 0, /* tp_dict */
2922 0, /* tp_descr_get */
2923 0, /* tp_descr_set */
2924 0, /* tp_dictoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002925 (initproc)bytearray_init, /* tp_init */
Christian Heimes44720832008-05-26 13:01:01 +00002926 PyType_GenericAlloc, /* tp_alloc */
2927 PyType_GenericNew, /* tp_new */
2928 PyObject_Del, /* tp_free */
2929};
2930
2931/*********************** Bytes Iterator ****************************/
2932
2933typedef struct {
2934 PyObject_HEAD
2935 Py_ssize_t it_index;
2936 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2937} bytesiterobject;
2938
2939static void
Benjamin Petersond6720012009-04-18 15:31:34 +00002940bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002941{
2942 _PyObject_GC_UNTRACK(it);
2943 Py_XDECREF(it->it_seq);
2944 PyObject_GC_Del(it);
2945}
2946
2947static int
Benjamin Petersond6720012009-04-18 15:31:34 +00002948bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002949{
2950 Py_VISIT(it->it_seq);
2951 return 0;
2952}
2953
2954static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002955bytearrayiter_next(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002956{
2957 PyByteArrayObject *seq;
2958 PyObject *item;
2959
2960 assert(it != NULL);
2961 seq = it->it_seq;
2962 if (seq == NULL)
2963 return NULL;
2964 assert(PyByteArray_Check(seq));
2965
2966 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2967 item = PyInt_FromLong(
2968 (unsigned char)seq->ob_bytes[it->it_index]);
2969 if (item != NULL)
2970 ++it->it_index;
2971 return item;
2972 }
2973
2974 Py_DECREF(seq);
2975 it->it_seq = NULL;
2976 return NULL;
2977}
2978
2979static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002980bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002981{
2982 Py_ssize_t len = 0;
2983 if (it->it_seq)
2984 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2985 return PyInt_FromSsize_t(len);
2986}
2987
2988PyDoc_STRVAR(length_hint_doc,
2989 "Private method returning an estimate of len(list(it)).");
2990
Benjamin Petersond6720012009-04-18 15:31:34 +00002991static PyMethodDef bytearrayiter_methods[] = {
2992 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002993 length_hint_doc},
2994 {NULL, NULL} /* sentinel */
2995};
2996
2997PyTypeObject PyByteArrayIter_Type = {
2998 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2999 "bytearray_iterator", /* tp_name */
3000 sizeof(bytesiterobject), /* tp_basicsize */
3001 0, /* tp_itemsize */
3002 /* methods */
Benjamin Petersond6720012009-04-18 15:31:34 +00003003 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00003004 0, /* tp_print */
3005 0, /* tp_getattr */
3006 0, /* tp_setattr */
3007 0, /* tp_compare */
3008 0, /* tp_repr */
3009 0, /* tp_as_number */
3010 0, /* tp_as_sequence */
3011 0, /* tp_as_mapping */
3012 0, /* tp_hash */
3013 0, /* tp_call */
3014 0, /* tp_str */
3015 PyObject_GenericGetAttr, /* tp_getattro */
3016 0, /* tp_setattro */
3017 0, /* tp_as_buffer */
3018 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3019 0, /* tp_doc */
Benjamin Petersond6720012009-04-18 15:31:34 +00003020 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes44720832008-05-26 13:01:01 +00003021 0, /* tp_clear */
3022 0, /* tp_richcompare */
3023 0, /* tp_weaklistoffset */
3024 PyObject_SelfIter, /* tp_iter */
Benjamin Petersond6720012009-04-18 15:31:34 +00003025 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3026 bytearrayiter_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00003027 0,
3028};
3029
3030static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003031bytearray_iter(PyObject *seq)
Christian Heimes44720832008-05-26 13:01:01 +00003032{
3033 bytesiterobject *it;
3034
3035 if (!PyByteArray_Check(seq)) {
3036 PyErr_BadInternalCall();
3037 return NULL;
3038 }
3039 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3040 if (it == NULL)
3041 return NULL;
3042 it->it_index = 0;
3043 Py_INCREF(seq);
3044 it->it_seq = (PyByteArrayObject *)seq;
3045 _PyObject_GC_TRACK(it);
3046 return (PyObject *)it;
3047}