blob: 87c6599df4f0a0270287a952e1ce11746aaa2886 [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
708 if (cur + step >= PyByteArray_GET_SIZE(self))
709 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;
716 if (cur < PyByteArray_GET_SIZE(self)) {
717 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? */
827 count = PyNumber_AsSsize_t(arg, PyExc_ValueError);
828 if (count == -1 && PyErr_Occurred())
829 PyErr_Clear();
830 else {
831 if (count < 0) {
832 PyErr_SetString(PyExc_ValueError, "negative count");
833 return -1;
834 }
835 if (count > 0) {
836 if (PyByteArray_Resize((PyObject *)self, count))
837 return -1;
838 memset(self->ob_bytes, 0, count);
839 }
840 return 0;
841 }
842
843 /* Use the buffer API */
844 if (PyObject_CheckBuffer(arg)) {
845 Py_ssize_t size;
846 Py_buffer view;
847 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
848 return -1;
849 size = view.len;
850 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
851 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
852 goto fail;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000853 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000854 return 0;
855 fail:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000856 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000857 return -1;
858 }
859
860 /* XXX Optimize this if the arguments is a list, tuple */
861
862 /* Get the iterator */
863 it = PyObject_GetIter(arg);
864 if (it == NULL)
865 return -1;
866 iternext = *Py_TYPE(it)->tp_iternext;
867
868 /* Run the iterator to exhaustion */
869 for (;;) {
870 PyObject *item;
Georg Brandl3e758462008-07-16 23:10:05 +0000871 int rc, value;
Christian Heimes44720832008-05-26 13:01:01 +0000872
873 /* Get the next item */
874 item = iternext(it);
875 if (item == NULL) {
876 if (PyErr_Occurred()) {
877 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
878 goto error;
879 PyErr_Clear();
880 }
881 break;
882 }
883
884 /* Interpret it as an int (__index__) */
Georg Brandl3e758462008-07-16 23:10:05 +0000885 rc = _getbytevalue(item, &value);
Christian Heimes44720832008-05-26 13:01:01 +0000886 Py_DECREF(item);
Georg Brandl3e758462008-07-16 23:10:05 +0000887 if (!rc)
Christian Heimes44720832008-05-26 13:01:01 +0000888 goto error;
889
Christian Heimes44720832008-05-26 13:01:01 +0000890 /* Append the byte */
891 if (Py_SIZE(self) < self->ob_alloc)
892 Py_SIZE(self)++;
893 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
894 goto error;
895 self->ob_bytes[Py_SIZE(self)-1] = value;
896 }
897
898 /* Clean up and return success */
899 Py_DECREF(it);
900 return 0;
901
902 error:
903 /* Error handling when it != NULL */
904 Py_DECREF(it);
905 return -1;
906}
907
908/* Mostly copied from string_repr, but without the
909 "smart quote" functionality. */
910static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000911bytearray_repr(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000912{
913 static const char *hexdigits = "0123456789abcdef";
914 const char *quote_prefix = "bytearray(b";
915 const char *quote_postfix = ")";
916 Py_ssize_t length = Py_SIZE(self);
917 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
918 size_t newsize = 14 + 4 * length;
919 PyObject *v;
920 if (newsize > PY_SSIZE_T_MAX || newsize / 4 - 3 != length) {
921 PyErr_SetString(PyExc_OverflowError,
922 "bytearray object is too large to make repr");
923 return NULL;
924 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000925 v = PyString_FromStringAndSize(NULL, newsize);
Christian Heimes44720832008-05-26 13:01:01 +0000926 if (v == NULL) {
927 return NULL;
928 }
929 else {
930 register Py_ssize_t i;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000931 register char c;
932 register char *p;
Christian Heimes44720832008-05-26 13:01:01 +0000933 int quote;
934
935 /* Figure out which quote to use; single is preferred */
936 quote = '\'';
937 {
938 char *test, *start;
939 start = PyByteArray_AS_STRING(self);
940 for (test = start; test < start+length; ++test) {
941 if (*test == '"') {
942 quote = '\''; /* back to single */
943 goto decided;
944 }
945 else if (*test == '\'')
946 quote = '"';
947 }
948 decided:
949 ;
950 }
951
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000952 p = PyString_AS_STRING(v);
Christian Heimes44720832008-05-26 13:01:01 +0000953 while (*quote_prefix)
954 *p++ = *quote_prefix++;
955 *p++ = quote;
956
957 for (i = 0; i < length; i++) {
958 /* There's at least enough room for a hex escape
959 and a closing quote. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000960 assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
Christian Heimes44720832008-05-26 13:01:01 +0000961 c = self->ob_bytes[i];
962 if (c == '\'' || c == '\\')
963 *p++ = '\\', *p++ = c;
964 else if (c == '\t')
965 *p++ = '\\', *p++ = 't';
966 else if (c == '\n')
967 *p++ = '\\', *p++ = 'n';
968 else if (c == '\r')
969 *p++ = '\\', *p++ = 'r';
970 else if (c == 0)
971 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
972 else if (c < ' ' || c >= 0x7f) {
973 *p++ = '\\';
974 *p++ = 'x';
975 *p++ = hexdigits[(c & 0xf0) >> 4];
976 *p++ = hexdigits[c & 0xf];
977 }
978 else
979 *p++ = c;
980 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000981 assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
Christian Heimes44720832008-05-26 13:01:01 +0000982 *p++ = quote;
983 while (*quote_postfix) {
984 *p++ = *quote_postfix++;
985 }
986 *p = '\0';
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000987 if (_PyString_Resize(&v, (p - PyString_AS_STRING(v)))) {
Christian Heimes44720832008-05-26 13:01:01 +0000988 Py_DECREF(v);
989 return NULL;
990 }
991 return v;
992 }
993}
994
995static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000996bytearray_str(PyObject *op)
Christian Heimes44720832008-05-26 13:01:01 +0000997{
998#if 0
999 if (Py_BytesWarningFlag) {
1000 if (PyErr_WarnEx(PyExc_BytesWarning,
1001 "str() on a bytearray instance", 1))
1002 return NULL;
1003 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001004 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes44720832008-05-26 13:01:01 +00001005#endif
1006 return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
1007}
1008
1009static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001010bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes44720832008-05-26 13:01:01 +00001011{
1012 Py_ssize_t self_size, other_size;
1013 Py_buffer self_bytes, other_bytes;
1014 PyObject *res;
1015 Py_ssize_t minsize;
1016 int cmp;
1017
1018 /* Bytes can be compared to anything that supports the (binary)
1019 buffer API. Except that a comparison with Unicode is always an
1020 error, even if the comparison is for equality. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001021#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00001022 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1023 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
1024 if (Py_BytesWarningFlag && op == Py_EQ) {
1025 if (PyErr_WarnEx(PyExc_BytesWarning,
Ezio Melottid2342082010-01-14 11:34:10 +00001026 "Comparison between bytearray and string", 1))
Christian Heimes44720832008-05-26 13:01:01 +00001027 return NULL;
1028 }
1029
1030 Py_INCREF(Py_NotImplemented);
1031 return Py_NotImplemented;
1032 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001033#endif
Christian Heimes44720832008-05-26 13:01:01 +00001034
1035 self_size = _getbuffer(self, &self_bytes);
1036 if (self_size < 0) {
1037 PyErr_Clear();
1038 Py_INCREF(Py_NotImplemented);
1039 return Py_NotImplemented;
1040 }
1041
1042 other_size = _getbuffer(other, &other_bytes);
1043 if (other_size < 0) {
1044 PyErr_Clear();
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001045 PyBuffer_Release(&self_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001046 Py_INCREF(Py_NotImplemented);
1047 return Py_NotImplemented;
1048 }
1049
1050 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1051 /* Shortcut: if the lengths differ, the objects differ */
1052 cmp = (op == Py_NE);
1053 }
1054 else {
1055 minsize = self_size;
1056 if (other_size < minsize)
1057 minsize = other_size;
1058
1059 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1060 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1061
1062 if (cmp == 0) {
1063 if (self_size < other_size)
1064 cmp = -1;
1065 else if (self_size > other_size)
1066 cmp = 1;
1067 }
1068
1069 switch (op) {
1070 case Py_LT: cmp = cmp < 0; break;
1071 case Py_LE: cmp = cmp <= 0; break;
1072 case Py_EQ: cmp = cmp == 0; break;
1073 case Py_NE: cmp = cmp != 0; break;
1074 case Py_GT: cmp = cmp > 0; break;
1075 case Py_GE: cmp = cmp >= 0; break;
1076 }
1077 }
1078
1079 res = cmp ? Py_True : Py_False;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001080 PyBuffer_Release(&self_bytes);
1081 PyBuffer_Release(&other_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001082 Py_INCREF(res);
1083 return res;
1084}
1085
1086static void
Benjamin Petersond6720012009-04-18 15:31:34 +00001087bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00001088{
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001089 if (self->ob_exports > 0) {
1090 PyErr_SetString(PyExc_SystemError,
Georg Brandl517cfdc2009-04-05 13:16:35 +00001091 "deallocated bytearray object has exported buffers");
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001092 PyErr_Print();
1093 }
Christian Heimes44720832008-05-26 13:01:01 +00001094 if (self->ob_bytes != 0) {
1095 PyMem_Free(self->ob_bytes);
1096 }
1097 Py_TYPE(self)->tp_free((PyObject *)self);
1098}
1099
1100
1101/* -------------------------------------------------------------------- */
1102/* Methods */
1103
1104#define STRINGLIB_CHAR char
Christian Heimes44720832008-05-26 13:01:01 +00001105#define STRINGLIB_LEN PyByteArray_GET_SIZE
1106#define STRINGLIB_STR PyByteArray_AS_STRING
1107#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrou64672132010-01-13 07:55:48 +00001108#define STRINGLIB_ISSPACE Py_ISSPACE
1109#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes44720832008-05-26 13:01:01 +00001110#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1111#define STRINGLIB_MUTABLE 1
1112
1113#include "stringlib/fastsearch.h"
1114#include "stringlib/count.h"
1115#include "stringlib/find.h"
1116#include "stringlib/partition.h"
Antoine Pitrou64672132010-01-13 07:55:48 +00001117#include "stringlib/split.h"
Christian Heimes44720832008-05-26 13:01:01 +00001118#include "stringlib/ctype.h"
1119#include "stringlib/transmogrify.h"
1120
1121
1122/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1123were copied from the old char* style string object. */
1124
Antoine Pitrou64672132010-01-13 07:55:48 +00001125/* helper macro to fixup start/end slice values */
1126#define ADJUST_INDICES(start, end, len) \
1127 if (end > len) \
1128 end = len; \
1129 else if (end < 0) { \
1130 end += len; \
1131 if (end < 0) \
1132 end = 0; \
1133 } \
1134 if (start < 0) { \
1135 start += len; \
1136 if (start < 0) \
1137 start = 0; \
1138 }
Christian Heimes44720832008-05-26 13:01:01 +00001139
1140Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Petersond6720012009-04-18 15:31:34 +00001141bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes44720832008-05-26 13:01:01 +00001142{
1143 PyObject *subobj;
1144 Py_buffer subbuf;
1145 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1146 Py_ssize_t res;
1147
1148 if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
1149 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1150 return -2;
1151 if (_getbuffer(subobj, &subbuf) < 0)
1152 return -2;
1153 if (dir > 0)
1154 res = stringlib_find_slice(
1155 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1156 subbuf.buf, subbuf.len, start, end);
1157 else
1158 res = stringlib_rfind_slice(
1159 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1160 subbuf.buf, subbuf.len, start, end);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001161 PyBuffer_Release(&subbuf);
Christian Heimes44720832008-05-26 13:01:01 +00001162 return res;
1163}
1164
1165PyDoc_STRVAR(find__doc__,
1166"B.find(sub [,start [,end]]) -> int\n\
1167\n\
1168Return the lowest index in B where subsection sub is found,\n\
1169such that sub is contained within s[start,end]. Optional\n\
1170arguments start and end are interpreted as in slice notation.\n\
1171\n\
1172Return -1 on failure.");
1173
1174static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001175bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001176{
Benjamin Petersond6720012009-04-18 15:31:34 +00001177 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001178 if (result == -2)
1179 return NULL;
1180 return PyInt_FromSsize_t(result);
1181}
1182
1183PyDoc_STRVAR(count__doc__,
1184"B.count(sub [,start [,end]]) -> int\n\
1185\n\
1186Return the number of non-overlapping occurrences of subsection sub in\n\
1187bytes B[start:end]. Optional arguments start and end are interpreted\n\
1188as in slice notation.");
1189
1190static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001191bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001192{
1193 PyObject *sub_obj;
1194 const char *str = PyByteArray_AS_STRING(self);
1195 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1196 Py_buffer vsub;
1197 PyObject *count_obj;
1198
1199 if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1200 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1201 return NULL;
1202
1203 if (_getbuffer(sub_obj, &vsub) < 0)
1204 return NULL;
1205
Antoine Pitrou64672132010-01-13 07:55:48 +00001206 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes44720832008-05-26 13:01:01 +00001207
1208 count_obj = PyInt_FromSsize_t(
Antoine Pitrou64672132010-01-13 07:55:48 +00001209 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes44720832008-05-26 13:01:01 +00001210 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001211 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00001212 return count_obj;
1213}
1214
1215
1216PyDoc_STRVAR(index__doc__,
1217"B.index(sub [,start [,end]]) -> int\n\
1218\n\
1219Like B.find() but raise ValueError when the subsection is not found.");
1220
1221static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001222bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001223{
Benjamin Petersond6720012009-04-18 15:31:34 +00001224 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001225 if (result == -2)
1226 return NULL;
1227 if (result == -1) {
1228 PyErr_SetString(PyExc_ValueError,
1229 "subsection not found");
1230 return NULL;
1231 }
1232 return PyInt_FromSsize_t(result);
1233}
1234
1235
1236PyDoc_STRVAR(rfind__doc__,
1237"B.rfind(sub [,start [,end]]) -> int\n\
1238\n\
1239Return the highest index in B where subsection sub is found,\n\
1240such that sub is contained within s[start,end]. Optional\n\
1241arguments start and end are interpreted as in slice notation.\n\
1242\n\
1243Return -1 on failure.");
1244
1245static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001246bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001247{
Benjamin Petersond6720012009-04-18 15:31:34 +00001248 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001249 if (result == -2)
1250 return NULL;
1251 return PyInt_FromSsize_t(result);
1252}
1253
1254
1255PyDoc_STRVAR(rindex__doc__,
1256"B.rindex(sub [,start [,end]]) -> int\n\
1257\n\
1258Like B.rfind() but raise ValueError when the subsection is not found.");
1259
1260static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001261bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001262{
Benjamin Petersond6720012009-04-18 15:31:34 +00001263 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001264 if (result == -2)
1265 return NULL;
1266 if (result == -1) {
1267 PyErr_SetString(PyExc_ValueError,
1268 "subsection not found");
1269 return NULL;
1270 }
1271 return PyInt_FromSsize_t(result);
1272}
1273
1274
1275static int
Benjamin Petersond6720012009-04-18 15:31:34 +00001276bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00001277{
1278 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1279 if (ival == -1 && PyErr_Occurred()) {
1280 Py_buffer varg;
1281 int pos;
1282 PyErr_Clear();
1283 if (_getbuffer(arg, &varg) < 0)
1284 return -1;
1285 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1286 varg.buf, varg.len, 0);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001287 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00001288 return pos >= 0;
1289 }
1290 if (ival < 0 || ival >= 256) {
1291 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1292 return -1;
1293 }
1294
1295 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1296}
1297
1298
1299/* Matches the end (direction >= 0) or start (direction < 0) of self
1300 * against substr, using the start and end arguments. Returns
1301 * -1 on error, 0 if not found and 1 if found.
1302 */
1303Py_LOCAL(int)
Benjamin Petersond6720012009-04-18 15:31:34 +00001304_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes44720832008-05-26 13:01:01 +00001305 Py_ssize_t end, int direction)
1306{
1307 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1308 const char* str;
1309 Py_buffer vsubstr;
1310 int rv = 0;
1311
1312 str = PyByteArray_AS_STRING(self);
1313
1314 if (_getbuffer(substr, &vsubstr) < 0)
1315 return -1;
1316
Antoine Pitrou64672132010-01-13 07:55:48 +00001317 ADJUST_INDICES(start, end, len);
Christian Heimes44720832008-05-26 13:01:01 +00001318
1319 if (direction < 0) {
1320 /* startswith */
1321 if (start+vsubstr.len > len) {
1322 goto done;
1323 }
1324 } else {
1325 /* endswith */
1326 if (end-start < vsubstr.len || start > len) {
1327 goto done;
1328 }
1329
1330 if (end-vsubstr.len > start)
1331 start = end - vsubstr.len;
1332 }
1333 if (end-start >= vsubstr.len)
1334 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1335
1336done:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001337 PyBuffer_Release(&vsubstr);
Christian Heimes44720832008-05-26 13:01:01 +00001338 return rv;
1339}
1340
1341
1342PyDoc_STRVAR(startswith__doc__,
1343"B.startswith(prefix [,start [,end]]) -> bool\n\
1344\n\
1345Return True if B starts with the specified prefix, False otherwise.\n\
1346With optional start, test B beginning at that position.\n\
1347With optional end, stop comparing B at that position.\n\
1348prefix can also be a tuple of strings to try.");
1349
1350static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001351bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001352{
1353 Py_ssize_t start = 0;
1354 Py_ssize_t end = PY_SSIZE_T_MAX;
1355 PyObject *subobj;
1356 int result;
1357
1358 if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
1359 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1360 return NULL;
1361 if (PyTuple_Check(subobj)) {
1362 Py_ssize_t i;
1363 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001364 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001365 PyTuple_GET_ITEM(subobj, i),
1366 start, end, -1);
1367 if (result == -1)
1368 return NULL;
1369 else if (result) {
1370 Py_RETURN_TRUE;
1371 }
1372 }
1373 Py_RETURN_FALSE;
1374 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001375 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001376 if (result == -1)
1377 return NULL;
1378 else
1379 return PyBool_FromLong(result);
1380}
1381
1382PyDoc_STRVAR(endswith__doc__,
1383"B.endswith(suffix [,start [,end]]) -> bool\n\
1384\n\
1385Return True if B ends with the specified suffix, False otherwise.\n\
1386With optional start, test B beginning at that position.\n\
1387With optional end, stop comparing B at that position.\n\
1388suffix can also be a tuple of strings to try.");
1389
1390static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001391bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001392{
1393 Py_ssize_t start = 0;
1394 Py_ssize_t end = PY_SSIZE_T_MAX;
1395 PyObject *subobj;
1396 int result;
1397
1398 if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
1399 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1400 return NULL;
1401 if (PyTuple_Check(subobj)) {
1402 Py_ssize_t i;
1403 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001404 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001405 PyTuple_GET_ITEM(subobj, i),
1406 start, end, +1);
1407 if (result == -1)
1408 return NULL;
1409 else if (result) {
1410 Py_RETURN_TRUE;
1411 }
1412 }
1413 Py_RETURN_FALSE;
1414 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001415 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001416 if (result == -1)
1417 return NULL;
1418 else
1419 return PyBool_FromLong(result);
1420}
1421
1422
1423PyDoc_STRVAR(translate__doc__,
1424"B.translate(table[, deletechars]) -> bytearray\n\
1425\n\
1426Return a copy of B, where all characters occurring in the\n\
1427optional argument deletechars are removed, and the remaining\n\
1428characters have been mapped through the given translation\n\
1429table, which must be a bytes object of length 256.");
1430
1431static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001432bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001433{
1434 register char *input, *output;
1435 register const char *table;
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001436 register Py_ssize_t i, c;
Christian Heimes44720832008-05-26 13:01:01 +00001437 PyObject *input_obj = (PyObject*)self;
1438 const char *output_start;
1439 Py_ssize_t inlen;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001440 PyObject *result = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001441 int trans_table[256];
Georg Brandl6425a2f2008-12-28 11:54:53 +00001442 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001443 Py_buffer vtable, vdel;
1444
1445 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1446 &tableobj, &delobj))
1447 return NULL;
1448
Georg Brandl6425a2f2008-12-28 11:54:53 +00001449 if (tableobj == Py_None) {
1450 table = NULL;
1451 tableobj = NULL;
1452 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00001453 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001454 } else {
1455 if (vtable.len != 256) {
1456 PyErr_SetString(PyExc_ValueError,
1457 "translation table must be 256 characters long");
Georg Brandlec812ca2009-07-22 11:57:15 +00001458 PyBuffer_Release(&vtable);
1459 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001460 }
1461 table = (const char*)vtable.buf;
Christian Heimes44720832008-05-26 13:01:01 +00001462 }
1463
1464 if (delobj != NULL) {
1465 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandlec812ca2009-07-22 11:57:15 +00001466 if (tableobj != NULL)
1467 PyBuffer_Release(&vtable);
1468 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001469 }
1470 }
1471 else {
1472 vdel.buf = NULL;
1473 vdel.len = 0;
1474 }
1475
Christian Heimes44720832008-05-26 13:01:01 +00001476 inlen = PyByteArray_GET_SIZE(input_obj);
1477 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1478 if (result == NULL)
1479 goto done;
1480 output_start = output = PyByteArray_AsString(result);
1481 input = PyByteArray_AS_STRING(input_obj);
1482
Georg Brandl6425a2f2008-12-28 11:54:53 +00001483 if (vdel.len == 0 && table != NULL) {
Christian Heimes44720832008-05-26 13:01:01 +00001484 /* If no deletions are required, use faster code */
1485 for (i = inlen; --i >= 0; ) {
1486 c = Py_CHARMASK(*input++);
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001487 *output++ = table[c];
Christian Heimes44720832008-05-26 13:01:01 +00001488 }
Christian Heimes44720832008-05-26 13:01:01 +00001489 goto done;
1490 }
Georg Brandl6425a2f2008-12-28 11:54:53 +00001491
1492 if (table == NULL) {
1493 for (i = 0; i < 256; i++)
1494 trans_table[i] = Py_CHARMASK(i);
1495 } else {
1496 for (i = 0; i < 256; i++)
1497 trans_table[i] = Py_CHARMASK(table[i]);
1498 }
Christian Heimes44720832008-05-26 13:01:01 +00001499
1500 for (i = 0; i < vdel.len; i++)
1501 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1502
1503 for (i = inlen; --i >= 0; ) {
1504 c = Py_CHARMASK(*input++);
1505 if (trans_table[c] != -1)
1506 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1507 continue;
Christian Heimes44720832008-05-26 13:01:01 +00001508 }
1509 /* Fix the size of the resulting string */
1510 if (inlen > 0)
1511 PyByteArray_Resize(result, output - output_start);
1512
1513done:
Georg Brandl6425a2f2008-12-28 11:54:53 +00001514 if (tableobj != NULL)
1515 PyBuffer_Release(&vtable);
Christian Heimes44720832008-05-26 13:01:01 +00001516 if (delobj != NULL)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001517 PyBuffer_Release(&vdel);
Christian Heimes44720832008-05-26 13:01:01 +00001518 return result;
1519}
1520
1521
Christian Heimes44720832008-05-26 13:01:01 +00001522/* find and count characters and substrings */
1523
1524#define findchar(target, target_len, c) \
1525 ((char *)memchr((const void *)(target), c, target_len))
1526
Christian Heimes44720832008-05-26 13:01:01 +00001527
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001528/* Bytes ops must return a string, create a copy */
Christian Heimes44720832008-05-26 13:01:01 +00001529Py_LOCAL(PyByteArrayObject *)
1530return_self(PyByteArrayObject *self)
1531{
Christian Heimes44720832008-05-26 13:01:01 +00001532 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1533 PyByteArray_AS_STRING(self),
1534 PyByteArray_GET_SIZE(self));
1535}
1536
1537Py_LOCAL_INLINE(Py_ssize_t)
1538countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1539{
1540 Py_ssize_t count=0;
1541 const char *start=target;
1542 const char *end=target+target_len;
1543
1544 while ( (start=findchar(start, end-start, c)) != NULL ) {
1545 count++;
1546 if (count >= maxcount)
1547 break;
1548 start += 1;
1549 }
1550 return count;
1551}
1552
Christian Heimes44720832008-05-26 13:01:01 +00001553
1554/* Algorithms for different cases of string replacement */
1555
1556/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1557Py_LOCAL(PyByteArrayObject *)
1558replace_interleave(PyByteArrayObject *self,
1559 const char *to_s, Py_ssize_t to_len,
1560 Py_ssize_t maxcount)
1561{
1562 char *self_s, *result_s;
1563 Py_ssize_t self_len, result_len;
1564 Py_ssize_t count, i, product;
1565 PyByteArrayObject *result;
1566
1567 self_len = PyByteArray_GET_SIZE(self);
1568
1569 /* 1 at the end plus 1 after every character */
1570 count = self_len+1;
1571 if (maxcount < count)
1572 count = maxcount;
1573
1574 /* Check for overflow */
1575 /* result_len = count * to_len + self_len; */
1576 product = count * to_len;
1577 if (product / to_len != count) {
1578 PyErr_SetString(PyExc_OverflowError,
1579 "replace string is too long");
1580 return NULL;
1581 }
1582 result_len = product + self_len;
1583 if (result_len < 0) {
1584 PyErr_SetString(PyExc_OverflowError,
1585 "replace string is too long");
1586 return NULL;
1587 }
1588
1589 if (! (result = (PyByteArrayObject *)
1590 PyByteArray_FromStringAndSize(NULL, result_len)) )
1591 return NULL;
1592
1593 self_s = PyByteArray_AS_STRING(self);
1594 result_s = PyByteArray_AS_STRING(result);
1595
1596 /* TODO: special case single character, which doesn't need memcpy */
1597
1598 /* Lay the first one down (guaranteed this will occur) */
1599 Py_MEMCPY(result_s, to_s, to_len);
1600 result_s += to_len;
1601 count -= 1;
1602
1603 for (i=0; i<count; i++) {
1604 *result_s++ = *self_s++;
1605 Py_MEMCPY(result_s, to_s, to_len);
1606 result_s += to_len;
1607 }
1608
1609 /* Copy the rest of the original string */
1610 Py_MEMCPY(result_s, self_s, self_len-i);
1611
1612 return result;
1613}
1614
1615/* Special case for deleting a single character */
1616/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1617Py_LOCAL(PyByteArrayObject *)
1618replace_delete_single_character(PyByteArrayObject *self,
1619 char from_c, Py_ssize_t maxcount)
1620{
1621 char *self_s, *result_s;
1622 char *start, *next, *end;
1623 Py_ssize_t self_len, result_len;
1624 Py_ssize_t count;
1625 PyByteArrayObject *result;
1626
1627 self_len = PyByteArray_GET_SIZE(self);
1628 self_s = PyByteArray_AS_STRING(self);
1629
1630 count = countchar(self_s, self_len, from_c, maxcount);
1631 if (count == 0) {
1632 return return_self(self);
1633 }
1634
1635 result_len = self_len - count; /* from_len == 1 */
1636 assert(result_len>=0);
1637
1638 if ( (result = (PyByteArrayObject *)
1639 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1640 return NULL;
1641 result_s = PyByteArray_AS_STRING(result);
1642
1643 start = self_s;
1644 end = self_s + self_len;
1645 while (count-- > 0) {
1646 next = findchar(start, end-start, from_c);
1647 if (next == NULL)
1648 break;
1649 Py_MEMCPY(result_s, start, next-start);
1650 result_s += (next-start);
1651 start = next+1;
1652 }
1653 Py_MEMCPY(result_s, start, end-start);
1654
1655 return result;
1656}
1657
1658/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1659
1660Py_LOCAL(PyByteArrayObject *)
1661replace_delete_substring(PyByteArrayObject *self,
1662 const char *from_s, Py_ssize_t from_len,
1663 Py_ssize_t maxcount)
1664{
1665 char *self_s, *result_s;
1666 char *start, *next, *end;
1667 Py_ssize_t self_len, result_len;
1668 Py_ssize_t count, offset;
1669 PyByteArrayObject *result;
1670
1671 self_len = PyByteArray_GET_SIZE(self);
1672 self_s = PyByteArray_AS_STRING(self);
1673
Antoine Pitrou64672132010-01-13 07:55:48 +00001674 count = stringlib_count(self_s, self_len,
1675 from_s, from_len,
1676 maxcount);
Christian Heimes44720832008-05-26 13:01:01 +00001677
1678 if (count == 0) {
1679 /* no matches */
1680 return return_self(self);
1681 }
1682
1683 result_len = self_len - (count * from_len);
1684 assert (result_len>=0);
1685
1686 if ( (result = (PyByteArrayObject *)
1687 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1688 return NULL;
1689
1690 result_s = PyByteArray_AS_STRING(result);
1691
1692 start = self_s;
1693 end = self_s + self_len;
1694 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001695 offset = stringlib_find(start, end-start,
1696 from_s, from_len,
1697 0);
Christian Heimes44720832008-05-26 13:01:01 +00001698 if (offset == -1)
1699 break;
1700 next = start + offset;
1701
1702 Py_MEMCPY(result_s, start, next-start);
1703
1704 result_s += (next-start);
1705 start = next+from_len;
1706 }
1707 Py_MEMCPY(result_s, start, end-start);
1708 return result;
1709}
1710
1711/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1712Py_LOCAL(PyByteArrayObject *)
1713replace_single_character_in_place(PyByteArrayObject *self,
1714 char from_c, char to_c,
1715 Py_ssize_t maxcount)
1716{
1717 char *self_s, *result_s, *start, *end, *next;
1718 Py_ssize_t self_len;
1719 PyByteArrayObject *result;
1720
1721 /* The result string will be the same size */
1722 self_s = PyByteArray_AS_STRING(self);
1723 self_len = PyByteArray_GET_SIZE(self);
1724
1725 next = findchar(self_s, self_len, from_c);
1726
1727 if (next == NULL) {
1728 /* No matches; return the original bytes */
1729 return return_self(self);
1730 }
1731
1732 /* Need to make a new bytes */
1733 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1734 if (result == NULL)
1735 return NULL;
1736 result_s = PyByteArray_AS_STRING(result);
1737 Py_MEMCPY(result_s, self_s, self_len);
1738
1739 /* change everything in-place, starting with this one */
1740 start = result_s + (next-self_s);
1741 *start = to_c;
1742 start++;
1743 end = result_s + self_len;
1744
1745 while (--maxcount > 0) {
1746 next = findchar(start, end-start, from_c);
1747 if (next == NULL)
1748 break;
1749 *next = to_c;
1750 start = next+1;
1751 }
1752
1753 return result;
1754}
1755
1756/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1757Py_LOCAL(PyByteArrayObject *)
1758replace_substring_in_place(PyByteArrayObject *self,
1759 const char *from_s, Py_ssize_t from_len,
1760 const char *to_s, Py_ssize_t to_len,
1761 Py_ssize_t maxcount)
1762{
1763 char *result_s, *start, *end;
1764 char *self_s;
1765 Py_ssize_t self_len, offset;
1766 PyByteArrayObject *result;
1767
1768 /* The result bytes will be the same size */
1769
1770 self_s = PyByteArray_AS_STRING(self);
1771 self_len = PyByteArray_GET_SIZE(self);
1772
Antoine Pitrou64672132010-01-13 07:55:48 +00001773 offset = stringlib_find(self_s, self_len,
1774 from_s, from_len,
1775 0);
Christian Heimes44720832008-05-26 13:01:01 +00001776 if (offset == -1) {
1777 /* No matches; return the original bytes */
1778 return return_self(self);
1779 }
1780
1781 /* Need to make a new bytes */
1782 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1783 if (result == NULL)
1784 return NULL;
1785 result_s = PyByteArray_AS_STRING(result);
1786 Py_MEMCPY(result_s, self_s, self_len);
1787
1788 /* change everything in-place, starting with this one */
1789 start = result_s + offset;
1790 Py_MEMCPY(start, to_s, from_len);
1791 start += from_len;
1792 end = result_s + self_len;
1793
1794 while ( --maxcount > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001795 offset = stringlib_find(start, end-start,
1796 from_s, from_len,
1797 0);
Christian Heimes44720832008-05-26 13:01:01 +00001798 if (offset==-1)
1799 break;
1800 Py_MEMCPY(start+offset, to_s, from_len);
1801 start += offset+from_len;
1802 }
1803
1804 return result;
1805}
1806
1807/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1808Py_LOCAL(PyByteArrayObject *)
1809replace_single_character(PyByteArrayObject *self,
1810 char from_c,
1811 const char *to_s, Py_ssize_t to_len,
1812 Py_ssize_t maxcount)
1813{
1814 char *self_s, *result_s;
1815 char *start, *next, *end;
1816 Py_ssize_t self_len, result_len;
1817 Py_ssize_t count, product;
1818 PyByteArrayObject *result;
1819
1820 self_s = PyByteArray_AS_STRING(self);
1821 self_len = PyByteArray_GET_SIZE(self);
1822
1823 count = countchar(self_s, self_len, from_c, maxcount);
1824 if (count == 0) {
1825 /* no matches, return unchanged */
1826 return return_self(self);
1827 }
1828
1829 /* use the difference between current and new, hence the "-1" */
1830 /* result_len = self_len + count * (to_len-1) */
1831 product = count * (to_len-1);
1832 if (product / (to_len-1) != count) {
1833 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1834 return NULL;
1835 }
1836 result_len = self_len + product;
1837 if (result_len < 0) {
1838 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1839 return NULL;
1840 }
1841
1842 if ( (result = (PyByteArrayObject *)
1843 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1844 return NULL;
1845 result_s = PyByteArray_AS_STRING(result);
1846
1847 start = self_s;
1848 end = self_s + self_len;
1849 while (count-- > 0) {
1850 next = findchar(start, end-start, from_c);
1851 if (next == NULL)
1852 break;
1853
1854 if (next == start) {
1855 /* replace with the 'to' */
1856 Py_MEMCPY(result_s, to_s, to_len);
1857 result_s += to_len;
1858 start += 1;
1859 } else {
1860 /* copy the unchanged old then the 'to' */
1861 Py_MEMCPY(result_s, start, next-start);
1862 result_s += (next-start);
1863 Py_MEMCPY(result_s, to_s, to_len);
1864 result_s += to_len;
1865 start = next+1;
1866 }
1867 }
1868 /* Copy the remainder of the remaining bytes */
1869 Py_MEMCPY(result_s, start, end-start);
1870
1871 return result;
1872}
1873
1874/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1875Py_LOCAL(PyByteArrayObject *)
1876replace_substring(PyByteArrayObject *self,
1877 const char *from_s, Py_ssize_t from_len,
1878 const char *to_s, Py_ssize_t to_len,
1879 Py_ssize_t maxcount)
1880{
1881 char *self_s, *result_s;
1882 char *start, *next, *end;
1883 Py_ssize_t self_len, result_len;
1884 Py_ssize_t count, offset, product;
1885 PyByteArrayObject *result;
1886
1887 self_s = PyByteArray_AS_STRING(self);
1888 self_len = PyByteArray_GET_SIZE(self);
1889
Antoine Pitrou64672132010-01-13 07:55:48 +00001890 count = stringlib_count(self_s, self_len,
1891 from_s, from_len,
1892 maxcount);
1893
Christian Heimes44720832008-05-26 13:01:01 +00001894 if (count == 0) {
1895 /* no matches, return unchanged */
1896 return return_self(self);
1897 }
1898
1899 /* Check for overflow */
1900 /* result_len = self_len + count * (to_len-from_len) */
1901 product = count * (to_len-from_len);
1902 if (product / (to_len-from_len) != count) {
1903 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1904 return NULL;
1905 }
1906 result_len = self_len + product;
1907 if (result_len < 0) {
1908 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1909 return NULL;
1910 }
1911
1912 if ( (result = (PyByteArrayObject *)
1913 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1914 return NULL;
1915 result_s = PyByteArray_AS_STRING(result);
1916
1917 start = self_s;
1918 end = self_s + self_len;
1919 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001920 offset = stringlib_find(start, end-start,
1921 from_s, from_len,
1922 0);
Christian Heimes44720832008-05-26 13:01:01 +00001923 if (offset == -1)
1924 break;
1925 next = start+offset;
1926 if (next == start) {
1927 /* replace with the 'to' */
1928 Py_MEMCPY(result_s, to_s, to_len);
1929 result_s += to_len;
1930 start += from_len;
1931 } else {
1932 /* copy the unchanged old then the 'to' */
1933 Py_MEMCPY(result_s, start, next-start);
1934 result_s += (next-start);
1935 Py_MEMCPY(result_s, to_s, to_len);
1936 result_s += to_len;
1937 start = next+from_len;
1938 }
1939 }
1940 /* Copy the remainder of the remaining bytes */
1941 Py_MEMCPY(result_s, start, end-start);
1942
1943 return result;
1944}
1945
1946
1947Py_LOCAL(PyByteArrayObject *)
1948replace(PyByteArrayObject *self,
1949 const char *from_s, Py_ssize_t from_len,
1950 const char *to_s, Py_ssize_t to_len,
1951 Py_ssize_t maxcount)
1952{
1953 if (maxcount < 0) {
1954 maxcount = PY_SSIZE_T_MAX;
1955 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1956 /* nothing to do; return the original bytes */
1957 return return_self(self);
1958 }
1959
1960 if (maxcount == 0 ||
1961 (from_len == 0 && to_len == 0)) {
1962 /* nothing to do; return the original bytes */
1963 return return_self(self);
1964 }
1965
1966 /* Handle zero-length special cases */
1967
1968 if (from_len == 0) {
1969 /* insert the 'to' bytes everywhere. */
1970 /* >>> "Python".replace("", ".") */
1971 /* '.P.y.t.h.o.n.' */
1972 return replace_interleave(self, to_s, to_len, maxcount);
1973 }
1974
1975 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1976 /* point for an empty self bytes to generate a non-empty bytes */
1977 /* Special case so the remaining code always gets a non-empty bytes */
1978 if (PyByteArray_GET_SIZE(self) == 0) {
1979 return return_self(self);
1980 }
1981
1982 if (to_len == 0) {
1983 /* delete all occurances of 'from' bytes */
1984 if (from_len == 1) {
1985 return replace_delete_single_character(
1986 self, from_s[0], maxcount);
1987 } else {
1988 return replace_delete_substring(self, from_s, from_len, maxcount);
1989 }
1990 }
1991
1992 /* Handle special case where both bytes have the same length */
1993
1994 if (from_len == to_len) {
1995 if (from_len == 1) {
1996 return replace_single_character_in_place(
1997 self,
1998 from_s[0],
1999 to_s[0],
2000 maxcount);
2001 } else {
2002 return replace_substring_in_place(
2003 self, from_s, from_len, to_s, to_len, maxcount);
2004 }
2005 }
2006
2007 /* Otherwise use the more generic algorithms */
2008 if (from_len == 1) {
2009 return replace_single_character(self, from_s[0],
2010 to_s, to_len, maxcount);
2011 } else {
2012 /* len('from')>=2, len('to')>=1 */
2013 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2014 }
2015}
2016
2017
2018PyDoc_STRVAR(replace__doc__,
2019"B.replace(old, new[, count]) -> bytes\n\
2020\n\
2021Return a copy of B with all occurrences of subsection\n\
2022old replaced by new. If the optional argument count is\n\
2023given, only the first count occurrences are replaced.");
2024
2025static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002026bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002027{
2028 Py_ssize_t count = -1;
2029 PyObject *from, *to, *res;
2030 Py_buffer vfrom, vto;
2031
2032 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2033 return NULL;
2034
2035 if (_getbuffer(from, &vfrom) < 0)
2036 return NULL;
2037 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002038 PyBuffer_Release(&vfrom);
Christian Heimes44720832008-05-26 13:01:01 +00002039 return NULL;
2040 }
2041
2042 res = (PyObject *)replace((PyByteArrayObject *) self,
2043 vfrom.buf, vfrom.len,
2044 vto.buf, vto.len, count);
2045
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002046 PyBuffer_Release(&vfrom);
2047 PyBuffer_Release(&vto);
Christian Heimes44720832008-05-26 13:01:01 +00002048 return res;
2049}
2050
Christian Heimes44720832008-05-26 13:01:01 +00002051PyDoc_STRVAR(split__doc__,
2052"B.split([sep[, maxsplit]]) -> list of bytearray\n\
2053\n\
2054Return a list of the sections in B, using sep as the delimiter.\n\
2055If sep is not given, B is split on ASCII whitespace characters\n\
2056(space, tab, return, newline, formfeed, vertical tab).\n\
2057If maxsplit is given, at most maxsplit splits are done.");
2058
2059static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002060bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002061{
Antoine Pitrou64672132010-01-13 07:55:48 +00002062 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2063 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002064 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002065 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002066 Py_buffer vsub;
Christian Heimes44720832008-05-26 13:01:01 +00002067
2068 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2069 return NULL;
2070 if (maxsplit < 0)
2071 maxsplit = PY_SSIZE_T_MAX;
2072
2073 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002074 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002075
2076 if (_getbuffer(subobj, &vsub) < 0)
2077 return NULL;
2078 sub = vsub.buf;
2079 n = vsub.len;
2080
Antoine Pitrou64672132010-01-13 07:55:48 +00002081 list = stringlib_split(
2082 (PyObject*) self, s, len, sub, n, maxsplit
2083 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002084 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002085 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002086}
2087
2088PyDoc_STRVAR(partition__doc__,
2089"B.partition(sep) -> (head, sep, tail)\n\
2090\n\
2091Searches for the separator sep in B, and returns the part before it,\n\
2092the separator itself, and the part after it. If the separator is not\n\
2093found, returns B and two empty bytearray objects.");
2094
2095static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002096bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002097{
2098 PyObject *bytesep, *result;
2099
2100 bytesep = PyByteArray_FromObject(sep_obj);
2101 if (! bytesep)
2102 return NULL;
2103
2104 result = stringlib_partition(
2105 (PyObject*) self,
2106 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2107 bytesep,
2108 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2109 );
2110
2111 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002112 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002113}
2114
2115PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti1fafaab2010-01-25 11:24:37 +00002116"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes44720832008-05-26 13:01:01 +00002117\n\
2118Searches for the separator sep in B, starting at the end of B,\n\
2119and returns the part before it, the separator itself, and the\n\
2120part after it. If the separator is not found, returns two empty\n\
2121bytearray objects and B.");
2122
2123static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002124bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002125{
2126 PyObject *bytesep, *result;
2127
2128 bytesep = PyByteArray_FromObject(sep_obj);
2129 if (! bytesep)
2130 return NULL;
2131
2132 result = stringlib_rpartition(
2133 (PyObject*) self,
2134 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2135 bytesep,
2136 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2137 );
2138
2139 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002140 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002141}
2142
2143PyDoc_STRVAR(rsplit__doc__,
2144"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2145\n\
2146Return a list of the sections in B, using sep as the delimiter,\n\
2147starting at the end of B and working to the front.\n\
2148If sep is not given, B is split on ASCII whitespace characters\n\
2149(space, tab, return, newline, formfeed, vertical tab).\n\
2150If maxsplit is given, at most maxsplit splits are done.");
2151
2152static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002153bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002154{
Antoine Pitrou64672132010-01-13 07:55:48 +00002155 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2156 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002157 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002158 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002159 Py_buffer vsub;
2160
2161 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2162 return NULL;
2163 if (maxsplit < 0)
2164 maxsplit = PY_SSIZE_T_MAX;
2165
2166 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002167 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002168
2169 if (_getbuffer(subobj, &vsub) < 0)
2170 return NULL;
2171 sub = vsub.buf;
2172 n = vsub.len;
2173
Antoine Pitrou64672132010-01-13 07:55:48 +00002174 list = stringlib_rsplit(
2175 (PyObject*) self, s, len, sub, n, maxsplit
2176 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002177 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002178 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002179}
2180
2181PyDoc_STRVAR(reverse__doc__,
2182"B.reverse() -> None\n\
2183\n\
2184Reverse the order of the values in B in place.");
2185static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002186bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes44720832008-05-26 13:01:01 +00002187{
2188 char swap, *head, *tail;
2189 Py_ssize_t i, j, n = Py_SIZE(self);
2190
2191 j = n / 2;
2192 head = self->ob_bytes;
2193 tail = head + n - 1;
2194 for (i = 0; i < j; i++) {
2195 swap = *head;
2196 *head++ = *tail;
2197 *tail-- = swap;
2198 }
2199
2200 Py_RETURN_NONE;
2201}
2202
2203PyDoc_STRVAR(insert__doc__,
2204"B.insert(index, int) -> None\n\
2205\n\
2206Insert a single item into the bytearray before the given index.");
2207static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002208bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002209{
Georg Brandl3e483f62008-07-16 22:57:41 +00002210 PyObject *value;
2211 int ival;
Christian Heimes44720832008-05-26 13:01:01 +00002212 Py_ssize_t where, n = Py_SIZE(self);
2213
Georg Brandl3e483f62008-07-16 22:57:41 +00002214 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes44720832008-05-26 13:01:01 +00002215 return NULL;
2216
2217 if (n == PY_SSIZE_T_MAX) {
2218 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002219 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002220 return NULL;
2221 }
Georg Brandl3e483f62008-07-16 22:57:41 +00002222 if (!_getbytevalue(value, &ival))
Christian Heimes44720832008-05-26 13:01:01 +00002223 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002224 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2225 return NULL;
2226
2227 if (where < 0) {
2228 where += n;
2229 if (where < 0)
2230 where = 0;
2231 }
2232 if (where > n)
2233 where = n;
2234 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl3e483f62008-07-16 22:57:41 +00002235 self->ob_bytes[where] = ival;
Christian Heimes44720832008-05-26 13:01:01 +00002236
2237 Py_RETURN_NONE;
2238}
2239
2240PyDoc_STRVAR(append__doc__,
2241"B.append(int) -> None\n\
2242\n\
2243Append a single item to the end of B.");
2244static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002245bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002246{
2247 int value;
2248 Py_ssize_t n = Py_SIZE(self);
2249
2250 if (! _getbytevalue(arg, &value))
2251 return NULL;
2252 if (n == PY_SSIZE_T_MAX) {
2253 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002254 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002255 return NULL;
2256 }
2257 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2258 return NULL;
2259
2260 self->ob_bytes[n] = value;
2261
2262 Py_RETURN_NONE;
2263}
2264
2265PyDoc_STRVAR(extend__doc__,
2266"B.extend(iterable int) -> None\n\
2267\n\
2268Append all the elements from the iterator or sequence to the\n\
2269end of B.");
2270static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002271bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002272{
Benjamin Petersond6720012009-04-18 15:31:34 +00002273 PyObject *it, *item, *bytearray_obj;
Christian Heimes44720832008-05-26 13:01:01 +00002274 Py_ssize_t buf_size = 0, len = 0;
2275 int value;
2276 char *buf;
2277
Benjamin Petersond6720012009-04-18 15:31:34 +00002278 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes44720832008-05-26 13:01:01 +00002279 if (PyObject_CheckBuffer(arg)) {
Benjamin Petersond6720012009-04-18 15:31:34 +00002280 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002281 return NULL;
2282
2283 Py_RETURN_NONE;
2284 }
2285
2286 it = PyObject_GetIter(arg);
2287 if (it == NULL)
2288 return NULL;
2289
2290 /* Try to determine the length of the argument. 32 is abitrary. */
2291 buf_size = _PyObject_LengthHint(arg, 32);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002292 if (buf_size == -1) {
2293 Py_DECREF(it);
2294 return NULL;
2295 }
Christian Heimes44720832008-05-26 13:01:01 +00002296
Benjamin Petersond6720012009-04-18 15:31:34 +00002297 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2298 if (bytearray_obj == NULL)
Christian Heimes44720832008-05-26 13:01:01 +00002299 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002300 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002301
2302 while ((item = PyIter_Next(it)) != NULL) {
2303 if (! _getbytevalue(item, &value)) {
2304 Py_DECREF(item);
2305 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002306 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002307 return NULL;
2308 }
2309 buf[len++] = value;
2310 Py_DECREF(item);
2311
2312 if (len >= buf_size) {
2313 buf_size = len + (len >> 1) + 1;
Benjamin Petersond6720012009-04-18 15:31:34 +00002314 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00002315 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002316 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002317 return NULL;
2318 }
2319 /* Recompute the `buf' pointer, since the resizing operation may
2320 have invalidated it. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002321 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002322 }
2323 }
2324 Py_DECREF(it);
2325
2326 /* Resize down to exact size. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002327 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2328 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002329 return NULL;
2330 }
2331
Benjamin Petersond6720012009-04-18 15:31:34 +00002332 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002333 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002334 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002335
2336 Py_RETURN_NONE;
2337}
2338
2339PyDoc_STRVAR(pop__doc__,
2340"B.pop([index]) -> int\n\
2341\n\
2342Remove and return a single item from B. If no index\n\
Andrew M. Kuchlingd8972642008-06-21 13:29:12 +00002343argument is given, will pop the last value.");
Christian Heimes44720832008-05-26 13:01:01 +00002344static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002345bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002346{
2347 int value;
2348 Py_ssize_t where = -1, n = Py_SIZE(self);
2349
2350 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2351 return NULL;
2352
2353 if (n == 0) {
2354 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002355 "cannot pop an empty bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002356 return NULL;
2357 }
2358 if (where < 0)
2359 where += Py_SIZE(self);
2360 if (where < 0 || where >= Py_SIZE(self)) {
2361 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2362 return NULL;
2363 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002364 if (!_canresize(self))
2365 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002366
2367 value = self->ob_bytes[where];
2368 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2369 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2370 return NULL;
2371
Mark Dickinsonc8a7c7c2009-09-06 10:03:31 +00002372 return PyInt_FromLong((unsigned char)value);
Christian Heimes44720832008-05-26 13:01:01 +00002373}
2374
2375PyDoc_STRVAR(remove__doc__,
2376"B.remove(int) -> None\n\
2377\n\
2378Remove the first occurance of a value in B.");
2379static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002380bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002381{
2382 int value;
2383 Py_ssize_t where, n = Py_SIZE(self);
2384
2385 if (! _getbytevalue(arg, &value))
2386 return NULL;
2387
2388 for (where = 0; where < n; where++) {
2389 if (self->ob_bytes[where] == value)
2390 break;
2391 }
2392 if (where == n) {
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002393 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002394 return NULL;
2395 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002396 if (!_canresize(self))
2397 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002398
2399 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2400 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2401 return NULL;
2402
2403 Py_RETURN_NONE;
2404}
2405
2406/* XXX These two helpers could be optimized if argsize == 1 */
2407
2408static Py_ssize_t
2409lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2410 void *argptr, Py_ssize_t argsize)
2411{
2412 Py_ssize_t i = 0;
2413 while (i < mysize && memchr(argptr, myptr[i], argsize))
2414 i++;
2415 return i;
2416}
2417
2418static Py_ssize_t
2419rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2420 void *argptr, Py_ssize_t argsize)
2421{
2422 Py_ssize_t i = mysize - 1;
2423 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2424 i--;
2425 return i + 1;
2426}
2427
2428PyDoc_STRVAR(strip__doc__,
2429"B.strip([bytes]) -> bytearray\n\
2430\n\
2431Strip leading and trailing bytes contained in the argument.\n\
2432If the argument is omitted, strip ASCII whitespace.");
2433static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002434bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002435{
2436 Py_ssize_t left, right, mysize, argsize;
2437 void *myptr, *argptr;
2438 PyObject *arg = Py_None;
2439 Py_buffer varg;
2440 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2441 return NULL;
2442 if (arg == Py_None) {
2443 argptr = "\t\n\r\f\v ";
2444 argsize = 6;
2445 }
2446 else {
2447 if (_getbuffer(arg, &varg) < 0)
2448 return NULL;
2449 argptr = varg.buf;
2450 argsize = varg.len;
2451 }
2452 myptr = self->ob_bytes;
2453 mysize = Py_SIZE(self);
2454 left = lstrip_helper(myptr, mysize, argptr, argsize);
2455 if (left == mysize)
2456 right = left;
2457 else
2458 right = rstrip_helper(myptr, mysize, argptr, argsize);
2459 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002460 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002461 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2462}
2463
2464PyDoc_STRVAR(lstrip__doc__,
2465"B.lstrip([bytes]) -> bytearray\n\
2466\n\
2467Strip leading bytes contained in the argument.\n\
2468If the argument is omitted, strip leading ASCII whitespace.");
2469static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002470bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002471{
2472 Py_ssize_t left, right, mysize, argsize;
2473 void *myptr, *argptr;
2474 PyObject *arg = Py_None;
2475 Py_buffer varg;
2476 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2477 return NULL;
2478 if (arg == Py_None) {
2479 argptr = "\t\n\r\f\v ";
2480 argsize = 6;
2481 }
2482 else {
2483 if (_getbuffer(arg, &varg) < 0)
2484 return NULL;
2485 argptr = varg.buf;
2486 argsize = varg.len;
2487 }
2488 myptr = self->ob_bytes;
2489 mysize = Py_SIZE(self);
2490 left = lstrip_helper(myptr, mysize, argptr, argsize);
2491 right = mysize;
2492 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002493 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002494 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2495}
2496
2497PyDoc_STRVAR(rstrip__doc__,
2498"B.rstrip([bytes]) -> bytearray\n\
2499\n\
2500Strip trailing bytes contained in the argument.\n\
2501If the argument is omitted, strip trailing ASCII whitespace.");
2502static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002503bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002504{
2505 Py_ssize_t left, right, mysize, argsize;
2506 void *myptr, *argptr;
2507 PyObject *arg = Py_None;
2508 Py_buffer varg;
2509 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2510 return NULL;
2511 if (arg == Py_None) {
2512 argptr = "\t\n\r\f\v ";
2513 argsize = 6;
2514 }
2515 else {
2516 if (_getbuffer(arg, &varg) < 0)
2517 return NULL;
2518 argptr = varg.buf;
2519 argsize = varg.len;
2520 }
2521 myptr = self->ob_bytes;
2522 mysize = Py_SIZE(self);
2523 left = 0;
2524 right = rstrip_helper(myptr, mysize, argptr, argsize);
2525 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002526 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002527 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2528}
2529
2530PyDoc_STRVAR(decode_doc,
2531"B.decode([encoding[, errors]]) -> unicode object.\n\
2532\n\
2533Decodes B using the codec registered for encoding. encoding defaults\n\
2534to the default encoding. errors may be given to set a different error\n\
2535handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2536a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2537as well as any other name registered with codecs.register_error that is\n\
2538able to handle UnicodeDecodeErrors.");
2539
2540static PyObject *
Benjamin Petersondc782b52009-09-18 21:46:21 +00002541bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes44720832008-05-26 13:01:01 +00002542{
2543 const char *encoding = NULL;
2544 const char *errors = NULL;
Benjamin Petersondc782b52009-09-18 21:46:21 +00002545 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes44720832008-05-26 13:01:01 +00002546
Benjamin Petersondc782b52009-09-18 21:46:21 +00002547 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes44720832008-05-26 13:01:01 +00002548 return NULL;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002549 if (encoding == NULL) {
2550#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002551 encoding = PyUnicode_GetDefaultEncoding();
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002552#else
2553 PyErr_SetString(PyExc_ValueError, "no encoding specified");
2554 return NULL;
2555#endif
2556 }
Christian Heimes44720832008-05-26 13:01:01 +00002557 return PyCodec_Decode(self, encoding, errors);
2558}
2559
2560PyDoc_STRVAR(alloc_doc,
2561"B.__alloc__() -> int\n\
2562\n\
2563Returns the number of bytes actually allocated.");
2564
2565static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002566bytearray_alloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002567{
2568 return PyInt_FromSsize_t(self->ob_alloc);
2569}
2570
2571PyDoc_STRVAR(join_doc,
2572"B.join(iterable_of_bytes) -> bytes\n\
2573\n\
2574Concatenates any number of bytearray objects, with B in between each pair.");
2575
2576static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002577bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002578{
2579 PyObject *seq;
2580 Py_ssize_t mysize = Py_SIZE(self);
2581 Py_ssize_t i;
2582 Py_ssize_t n;
2583 PyObject **items;
2584 Py_ssize_t totalsize = 0;
2585 PyObject *result;
2586 char *dest;
2587
2588 seq = PySequence_Fast(it, "can only join an iterable");
2589 if (seq == NULL)
2590 return NULL;
2591 n = PySequence_Fast_GET_SIZE(seq);
2592 items = PySequence_Fast_ITEMS(seq);
2593
2594 /* Compute the total size, and check that they are all bytes */
2595 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2596 for (i = 0; i < n; i++) {
2597 PyObject *obj = items[i];
2598 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2599 PyErr_Format(PyExc_TypeError,
2600 "can only join an iterable of bytes "
2601 "(item %ld has type '%.100s')",
2602 /* XXX %ld isn't right on Win64 */
2603 (long)i, Py_TYPE(obj)->tp_name);
2604 goto error;
2605 }
2606 if (i > 0)
2607 totalsize += mysize;
2608 totalsize += Py_SIZE(obj);
2609 if (totalsize < 0) {
2610 PyErr_NoMemory();
2611 goto error;
2612 }
2613 }
2614
2615 /* Allocate the result, and copy the bytes */
2616 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2617 if (result == NULL)
2618 goto error;
2619 dest = PyByteArray_AS_STRING(result);
2620 for (i = 0; i < n; i++) {
2621 PyObject *obj = items[i];
2622 Py_ssize_t size = Py_SIZE(obj);
2623 char *buf;
2624 if (PyByteArray_Check(obj))
2625 buf = PyByteArray_AS_STRING(obj);
2626 else
2627 buf = PyBytes_AS_STRING(obj);
2628 if (i) {
2629 memcpy(dest, self->ob_bytes, mysize);
2630 dest += mysize;
2631 }
2632 memcpy(dest, buf, size);
2633 dest += size;
2634 }
2635
2636 /* Done */
2637 Py_DECREF(seq);
2638 return result;
2639
2640 /* Error handling */
2641 error:
2642 Py_DECREF(seq);
2643 return NULL;
2644}
2645
Antoine Pitrou64672132010-01-13 07:55:48 +00002646PyDoc_STRVAR(splitlines__doc__,
2647"B.splitlines([keepends]) -> list of lines\n\
2648\n\
2649Return a list of the lines in B, breaking at line boundaries.\n\
2650Line breaks are not included in the resulting list unless keepends\n\
2651is given and true.");
2652
2653static PyObject*
2654bytearray_splitlines(PyObject *self, PyObject *args)
2655{
2656 int keepends = 0;
2657
2658 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2659 return NULL;
2660
2661 return stringlib_splitlines(
2662 (PyObject*) self, PyByteArray_AS_STRING(self),
2663 PyByteArray_GET_SIZE(self), keepends
2664 );
2665}
2666
Christian Heimes44720832008-05-26 13:01:01 +00002667PyDoc_STRVAR(fromhex_doc,
2668"bytearray.fromhex(string) -> bytearray\n\
2669\n\
2670Create a bytearray object from a string of hexadecimal numbers.\n\
2671Spaces between two numbers are accepted.\n\
2672Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2673
2674static int
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002675hex_digit_to_int(char c)
Christian Heimes44720832008-05-26 13:01:01 +00002676{
Eric Smithcac7af62009-04-27 19:04:37 +00002677 if (Py_ISDIGIT(c))
Christian Heimes44720832008-05-26 13:01:01 +00002678 return c - '0';
2679 else {
Eric Smithcac7af62009-04-27 19:04:37 +00002680 if (Py_ISUPPER(c))
2681 c = Py_TOLOWER(c);
Christian Heimes44720832008-05-26 13:01:01 +00002682 if (c >= 'a' && c <= 'f')
2683 return c - 'a' + 10;
2684 }
2685 return -1;
2686}
2687
2688static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002689bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002690{
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002691 PyObject *newbytes;
Christian Heimes44720832008-05-26 13:01:01 +00002692 char *buf;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002693 char *hex;
Christian Heimes44720832008-05-26 13:01:01 +00002694 Py_ssize_t hexlen, byteslen, i, j;
2695 int top, bot;
2696
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002697 if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
Christian Heimes44720832008-05-26 13:01:01 +00002698 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002699 byteslen = hexlen/2; /* This overestimates if there are spaces */
2700 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2701 if (!newbytes)
2702 return NULL;
2703 buf = PyByteArray_AS_STRING(newbytes);
2704 for (i = j = 0; i < hexlen; i += 2) {
2705 /* skip over spaces in the input */
2706 while (hex[i] == ' ')
2707 i++;
2708 if (i >= hexlen)
2709 break;
2710 top = hex_digit_to_int(hex[i]);
2711 bot = hex_digit_to_int(hex[i+1]);
2712 if (top == -1 || bot == -1) {
2713 PyErr_Format(PyExc_ValueError,
2714 "non-hexadecimal number found in "
2715 "fromhex() arg at position %zd", i);
2716 goto error;
2717 }
2718 buf[j++] = (top << 4) + bot;
2719 }
2720 if (PyByteArray_Resize(newbytes, j) < 0)
2721 goto error;
2722 return newbytes;
2723
2724 error:
2725 Py_DECREF(newbytes);
2726 return NULL;
2727}
2728
2729PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2730
2731static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002732bytearray_reduce(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002733{
2734 PyObject *latin1, *dict;
2735 if (self->ob_bytes)
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002736#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002737 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2738 Py_SIZE(self), NULL);
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002739#else
Mark Dickinson9d109742009-10-15 15:18:55 +00002740 latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002741#endif
Christian Heimes44720832008-05-26 13:01:01 +00002742 else
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002743#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002744 latin1 = PyUnicode_FromString("");
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002745#else
2746 latin1 = PyString_FromString("");
2747#endif
Christian Heimes44720832008-05-26 13:01:01 +00002748
2749 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2750 if (dict == NULL) {
2751 PyErr_Clear();
2752 dict = Py_None;
2753 Py_INCREF(dict);
2754 }
2755
2756 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2757}
2758
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002759PyDoc_STRVAR(sizeof_doc,
2760"B.__sizeof__() -> int\n\
2761 \n\
2762Returns the size of B in memory, in bytes");
2763static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002764bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002765{
Georg Brandl517cfdc2009-04-05 13:16:35 +00002766 Py_ssize_t res;
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002767
Georg Brandl517cfdc2009-04-05 13:16:35 +00002768 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2769 return PyInt_FromSsize_t(res);
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002770}
2771
Benjamin Petersond6720012009-04-18 15:31:34 +00002772static PySequenceMethods bytearray_as_sequence = {
2773 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes44720832008-05-26 13:01:01 +00002774 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Petersond6720012009-04-18 15:31:34 +00002775 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2776 (ssizeargfunc)bytearray_getitem, /* sq_item */
2777 0, /* sq_slice */
2778 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2779 0, /* sq_ass_slice */
2780 (objobjproc)bytearray_contains, /* sq_contains */
2781 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2782 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes44720832008-05-26 13:01:01 +00002783};
2784
Benjamin Petersond6720012009-04-18 15:31:34 +00002785static PyMappingMethods bytearray_as_mapping = {
2786 (lenfunc)bytearray_length,
2787 (binaryfunc)bytearray_subscript,
2788 (objobjargproc)bytearray_ass_subscript,
Christian Heimes44720832008-05-26 13:01:01 +00002789};
2790
Benjamin Petersond6720012009-04-18 15:31:34 +00002791static PyBufferProcs bytearray_as_buffer = {
2792 (readbufferproc)bytearray_buffer_getreadbuf,
2793 (writebufferproc)bytearray_buffer_getwritebuf,
2794 (segcountproc)bytearray_buffer_getsegcount,
2795 (charbufferproc)bytearray_buffer_getcharbuf,
2796 (getbufferproc)bytearray_getbuffer,
2797 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes44720832008-05-26 13:01:01 +00002798};
2799
2800static PyMethodDef
Benjamin Petersond6720012009-04-18 15:31:34 +00002801bytearray_methods[] = {
2802 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2803 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2804 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2805 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002806 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2807 _Py_capitalize__doc__},
2808 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002809 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Petersondc782b52009-09-18 21:46:21 +00002810 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002811 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002812 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2813 expandtabs__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002814 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2815 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2816 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes44720832008-05-26 13:01:01 +00002817 fromhex_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002818 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2819 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002820 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2821 _Py_isalnum__doc__},
2822 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2823 _Py_isalpha__doc__},
2824 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2825 _Py_isdigit__doc__},
2826 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2827 _Py_islower__doc__},
2828 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2829 _Py_isspace__doc__},
2830 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2831 _Py_istitle__doc__},
2832 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2833 _Py_isupper__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002834 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes44720832008-05-26 13:01:01 +00002835 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2836 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002837 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2838 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2839 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2840 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2841 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2842 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2843 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2844 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002845 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002846 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2847 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2848 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2849 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrou64672132010-01-13 07:55:48 +00002850 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002851 splitlines__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002852 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes44720832008-05-26 13:01:01 +00002853 startswith__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002854 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002855 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2856 _Py_swapcase__doc__},
2857 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002858 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002859 translate__doc__},
2860 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2861 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2862 {NULL}
2863};
2864
Benjamin Petersond6720012009-04-18 15:31:34 +00002865PyDoc_STRVAR(bytearray_doc,
Christian Heimes44720832008-05-26 13:01:01 +00002866"bytearray(iterable_of_ints) -> bytearray.\n\
2867bytearray(string, encoding[, errors]) -> bytearray.\n\
2868bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
2869bytearray(memory_view) -> bytearray.\n\
2870\n\
2871Construct an mutable bytearray object from:\n\
2872 - an iterable yielding integers in range(256)\n\
2873 - a text string encoded using the specified encoding\n\
2874 - a bytes or a bytearray object\n\
2875 - any object implementing the buffer API.\n\
2876\n\
2877bytearray(int) -> bytearray.\n\
2878\n\
2879Construct a zero-initialized bytearray of the given length.");
2880
2881
Benjamin Petersond6720012009-04-18 15:31:34 +00002882static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes44720832008-05-26 13:01:01 +00002883
2884PyTypeObject PyByteArray_Type = {
2885 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2886 "bytearray",
2887 sizeof(PyByteArrayObject),
2888 0,
Benjamin Petersond6720012009-04-18 15:31:34 +00002889 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00002890 0, /* tp_print */
2891 0, /* tp_getattr */
2892 0, /* tp_setattr */
2893 0, /* tp_compare */
Benjamin Petersond6720012009-04-18 15:31:34 +00002894 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes44720832008-05-26 13:01:01 +00002895 0, /* tp_as_number */
Benjamin Petersond6720012009-04-18 15:31:34 +00002896 &bytearray_as_sequence, /* tp_as_sequence */
2897 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes44720832008-05-26 13:01:01 +00002898 0, /* tp_hash */
2899 0, /* tp_call */
Benjamin Petersond6720012009-04-18 15:31:34 +00002900 bytearray_str, /* tp_str */
Christian Heimes44720832008-05-26 13:01:01 +00002901 PyObject_GenericGetAttr, /* tp_getattro */
2902 0, /* tp_setattro */
Benjamin Petersond6720012009-04-18 15:31:34 +00002903 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes44720832008-05-26 13:01:01 +00002904 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2905 Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
Benjamin Petersond6720012009-04-18 15:31:34 +00002906 bytearray_doc, /* tp_doc */
Christian Heimes44720832008-05-26 13:01:01 +00002907 0, /* tp_traverse */
2908 0, /* tp_clear */
Benjamin Petersond6720012009-04-18 15:31:34 +00002909 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes44720832008-05-26 13:01:01 +00002910 0, /* tp_weaklistoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002911 bytearray_iter, /* tp_iter */
Christian Heimes44720832008-05-26 13:01:01 +00002912 0, /* tp_iternext */
Benjamin Petersond6720012009-04-18 15:31:34 +00002913 bytearray_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00002914 0, /* tp_members */
2915 0, /* tp_getset */
2916 0, /* tp_base */
2917 0, /* tp_dict */
2918 0, /* tp_descr_get */
2919 0, /* tp_descr_set */
2920 0, /* tp_dictoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002921 (initproc)bytearray_init, /* tp_init */
Christian Heimes44720832008-05-26 13:01:01 +00002922 PyType_GenericAlloc, /* tp_alloc */
2923 PyType_GenericNew, /* tp_new */
2924 PyObject_Del, /* tp_free */
2925};
2926
2927/*********************** Bytes Iterator ****************************/
2928
2929typedef struct {
2930 PyObject_HEAD
2931 Py_ssize_t it_index;
2932 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2933} bytesiterobject;
2934
2935static void
Benjamin Petersond6720012009-04-18 15:31:34 +00002936bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002937{
2938 _PyObject_GC_UNTRACK(it);
2939 Py_XDECREF(it->it_seq);
2940 PyObject_GC_Del(it);
2941}
2942
2943static int
Benjamin Petersond6720012009-04-18 15:31:34 +00002944bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002945{
2946 Py_VISIT(it->it_seq);
2947 return 0;
2948}
2949
2950static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002951bytearrayiter_next(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002952{
2953 PyByteArrayObject *seq;
2954 PyObject *item;
2955
2956 assert(it != NULL);
2957 seq = it->it_seq;
2958 if (seq == NULL)
2959 return NULL;
2960 assert(PyByteArray_Check(seq));
2961
2962 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2963 item = PyInt_FromLong(
2964 (unsigned char)seq->ob_bytes[it->it_index]);
2965 if (item != NULL)
2966 ++it->it_index;
2967 return item;
2968 }
2969
2970 Py_DECREF(seq);
2971 it->it_seq = NULL;
2972 return NULL;
2973}
2974
2975static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002976bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002977{
2978 Py_ssize_t len = 0;
2979 if (it->it_seq)
2980 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2981 return PyInt_FromSsize_t(len);
2982}
2983
2984PyDoc_STRVAR(length_hint_doc,
2985 "Private method returning an estimate of len(list(it)).");
2986
Benjamin Petersond6720012009-04-18 15:31:34 +00002987static PyMethodDef bytearrayiter_methods[] = {
2988 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002989 length_hint_doc},
2990 {NULL, NULL} /* sentinel */
2991};
2992
2993PyTypeObject PyByteArrayIter_Type = {
2994 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2995 "bytearray_iterator", /* tp_name */
2996 sizeof(bytesiterobject), /* tp_basicsize */
2997 0, /* tp_itemsize */
2998 /* methods */
Benjamin Petersond6720012009-04-18 15:31:34 +00002999 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00003000 0, /* tp_print */
3001 0, /* tp_getattr */
3002 0, /* tp_setattr */
3003 0, /* tp_compare */
3004 0, /* tp_repr */
3005 0, /* tp_as_number */
3006 0, /* tp_as_sequence */
3007 0, /* tp_as_mapping */
3008 0, /* tp_hash */
3009 0, /* tp_call */
3010 0, /* tp_str */
3011 PyObject_GenericGetAttr, /* tp_getattro */
3012 0, /* tp_setattro */
3013 0, /* tp_as_buffer */
3014 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3015 0, /* tp_doc */
Benjamin Petersond6720012009-04-18 15:31:34 +00003016 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes44720832008-05-26 13:01:01 +00003017 0, /* tp_clear */
3018 0, /* tp_richcompare */
3019 0, /* tp_weaklistoffset */
3020 PyObject_SelfIter, /* tp_iter */
Benjamin Petersond6720012009-04-18 15:31:34 +00003021 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3022 bytearrayiter_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00003023 0,
3024};
3025
3026static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003027bytearray_iter(PyObject *seq)
Christian Heimes44720832008-05-26 13:01:01 +00003028{
3029 bytesiterobject *it;
3030
3031 if (!PyByteArray_Check(seq)) {
3032 PyErr_BadInternalCall();
3033 return NULL;
3034 }
3035 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3036 if (it == NULL)
3037 return NULL;
3038 it->it_index = 0;
3039 Py_INCREF(seq);
3040 it->it_seq = (PyByteArrayObject *)seq;
3041 _PyObject_GC_TRACK(it);
3042 return (PyObject *)it;
3043}