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