blob: 21c58ce5f4aae6d4965c60a15cac63fdb1c9f574 [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{
Antoine Pitrou619f16e2010-06-09 16:24:00 +0000109 int ret;
110 void *ptr;
111 if (view == NULL) {
112 obj->ob_exports++;
113 return 0;
114 }
115 ptr = (void *) PyByteArray_AS_STRING(obj);
116 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
117 if (ret >= 0) {
118 obj->ob_exports++;
119 }
120 return ret;
Christian Heimes44720832008-05-26 13:01:01 +0000121}
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{
Antoine Pitrou619f16e2010-06-09 16:24:00 +0000126 obj->ob_exports--;
Christian Heimes44720832008-05-26 13:01:01 +0000127}
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)) {
Christian Heimes146a5fe2012-11-03 23:07:59 +0100639 int err;
Ezio Melotti67dc4a82012-11-03 21:10:45 +0200640 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
641 PyErr_SetString(PyExc_TypeError,
642 "can assign only bytes, buffers, or iterables "
643 "of ints in range(0, 256)");
644 return -1;
645 }
Georg Brandl28dadd92011-02-25 10:50:32 +0000646 /* Make a copy and call this function recursively */
Christian Heimes44720832008-05-26 13:01:01 +0000647 values = PyByteArray_FromObject(values);
648 if (values == NULL)
649 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000650 err = bytearray_ass_subscript(self, index, values);
Christian Heimes44720832008-05-26 13:01:01 +0000651 Py_DECREF(values);
652 return err;
653 }
654 else {
655 assert(PyByteArray_Check(values));
656 bytes = ((PyByteArrayObject *)values)->ob_bytes;
657 needed = Py_SIZE(values);
658 }
659 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
660 if ((step < 0 && start < stop) ||
661 (step > 0 && start > stop))
662 stop = start;
663 if (step == 1) {
664 if (slicelen != needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000665 if (!_canresize(self))
666 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000667 if (slicelen > needed) {
668 /*
669 0 start stop old_size
670 | |<---slicelen--->|<-----tomove------>|
671 | |<-needed->|<-----tomove------>|
672 0 lo new_hi new_size
673 */
674 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
675 Py_SIZE(self) - stop);
676 }
677 if (PyByteArray_Resize((PyObject *)self,
678 Py_SIZE(self) + needed - slicelen) < 0)
679 return -1;
680 if (slicelen < needed) {
681 /*
682 0 lo hi old_size
683 | |<-avail->|<-----tomove------>|
684 | |<----needed---->|<-----tomove------>|
685 0 lo new_hi new_size
686 */
687 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
688 Py_SIZE(self) - start - needed);
689 }
690 }
691
692 if (needed > 0)
693 memcpy(self->ob_bytes + start, bytes, needed);
694
695 return 0;
696 }
697 else {
698 if (needed == 0) {
699 /* Delete slice */
Mark Dickinson36ecd672010-01-29 17:11:39 +0000700 size_t cur;
701 Py_ssize_t i;
Christian Heimes44720832008-05-26 13:01:01 +0000702
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000703 if (!_canresize(self))
704 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000705 if (step < 0) {
706 stop = start + 1;
707 start = stop + step * (slicelen - 1) - 1;
708 step = -step;
709 }
710 for (cur = start, i = 0;
711 i < slicelen; cur += step, i++) {
712 Py_ssize_t lim = step - 1;
713
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000714 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes44720832008-05-26 13:01:01 +0000715 lim = PyByteArray_GET_SIZE(self) - cur - 1;
716
717 memmove(self->ob_bytes + cur - i,
718 self->ob_bytes + cur + 1, lim);
719 }
720 /* Move the tail of the bytes, in one chunk */
721 cur = start + slicelen*step;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000722 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Christian Heimes44720832008-05-26 13:01:01 +0000723 memmove(self->ob_bytes + cur - slicelen,
724 self->ob_bytes + cur,
725 PyByteArray_GET_SIZE(self) - cur);
726 }
727 if (PyByteArray_Resize((PyObject *)self,
728 PyByteArray_GET_SIZE(self) - slicelen) < 0)
729 return -1;
730
731 return 0;
732 }
733 else {
734 /* Assign slice */
735 Py_ssize_t cur, i;
736
737 if (needed != slicelen) {
738 PyErr_Format(PyExc_ValueError,
739 "attempt to assign bytes of size %zd "
740 "to extended slice of size %zd",
741 needed, slicelen);
742 return -1;
743 }
744 for (cur = start, i = 0; i < slicelen; cur += step, i++)
745 self->ob_bytes[cur] = bytes[i];
746 return 0;
747 }
748 }
749}
750
751static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000752bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes44720832008-05-26 13:01:01 +0000753{
754 static char *kwlist[] = {"source", "encoding", "errors", 0};
755 PyObject *arg = NULL;
756 const char *encoding = NULL;
757 const char *errors = NULL;
758 Py_ssize_t count;
759 PyObject *it;
760 PyObject *(*iternext)(PyObject *);
761
762 if (Py_SIZE(self) != 0) {
763 /* Empty previous contents (yes, do this first of all!) */
764 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
765 return -1;
766 }
767
768 /* Parse arguments */
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000769 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes44720832008-05-26 13:01:01 +0000770 &arg, &encoding, &errors))
771 return -1;
772
773 /* Make a quick exit if no first argument */
774 if (arg == NULL) {
775 if (encoding != NULL || errors != NULL) {
776 PyErr_SetString(PyExc_TypeError,
777 "encoding or errors without sequence argument");
778 return -1;
779 }
780 return 0;
781 }
782
783 if (PyBytes_Check(arg)) {
784 PyObject *new, *encoded;
785 if (encoding != NULL) {
786 encoded = PyCodec_Encode(arg, encoding, errors);
787 if (encoded == NULL)
788 return -1;
789 assert(PyBytes_Check(encoded));
790 }
791 else {
792 encoded = arg;
793 Py_INCREF(arg);
794 }
Benjamin Petersond6720012009-04-18 15:31:34 +0000795 new = bytearray_iconcat(self, arg);
Christian Heimes44720832008-05-26 13:01:01 +0000796 Py_DECREF(encoded);
797 if (new == NULL)
798 return -1;
799 Py_DECREF(new);
800 return 0;
801 }
802
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000803#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +0000804 if (PyUnicode_Check(arg)) {
805 /* Encode via the codec registry */
806 PyObject *encoded, *new;
807 if (encoding == NULL) {
808 PyErr_SetString(PyExc_TypeError,
809 "unicode argument without an encoding");
810 return -1;
811 }
812 encoded = PyCodec_Encode(arg, encoding, errors);
813 if (encoded == NULL)
814 return -1;
815 assert(PyBytes_Check(encoded));
Benjamin Petersond6720012009-04-18 15:31:34 +0000816 new = bytearray_iconcat(self, encoded);
Christian Heimes44720832008-05-26 13:01:01 +0000817 Py_DECREF(encoded);
818 if (new == NULL)
819 return -1;
820 Py_DECREF(new);
821 return 0;
822 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000823#endif
Christian Heimes44720832008-05-26 13:01:01 +0000824
825 /* If it's not unicode, there can't be encoding or errors */
826 if (encoding != NULL || errors != NULL) {
827 PyErr_SetString(PyExc_TypeError,
828 "encoding or errors without a string argument");
829 return -1;
830 }
831
832 /* Is it an int? */
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000833 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
834 if (count == -1 && PyErr_Occurred()) {
835 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes44720832008-05-26 13:01:01 +0000836 return -1;
Benjamin Petersonae530c22010-04-16 22:52:44 +0000837 PyErr_Clear();
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000838 }
839 else if (count < 0) {
840 PyErr_SetString(PyExc_ValueError, "negative count");
841 return -1;
842 }
843 else {
Christian Heimes44720832008-05-26 13:01:01 +0000844 if (count > 0) {
845 if (PyByteArray_Resize((PyObject *)self, count))
846 return -1;
847 memset(self->ob_bytes, 0, count);
848 }
849 return 0;
850 }
851
852 /* Use the buffer API */
853 if (PyObject_CheckBuffer(arg)) {
854 Py_ssize_t size;
855 Py_buffer view;
856 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
857 return -1;
858 size = view.len;
859 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
860 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
861 goto fail;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000862 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000863 return 0;
864 fail:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000865 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000866 return -1;
867 }
868
869 /* XXX Optimize this if the arguments is a list, tuple */
870
871 /* Get the iterator */
872 it = PyObject_GetIter(arg);
873 if (it == NULL)
874 return -1;
875 iternext = *Py_TYPE(it)->tp_iternext;
876
877 /* Run the iterator to exhaustion */
878 for (;;) {
879 PyObject *item;
Georg Brandl3e758462008-07-16 23:10:05 +0000880 int rc, value;
Christian Heimes44720832008-05-26 13:01:01 +0000881
882 /* Get the next item */
883 item = iternext(it);
884 if (item == NULL) {
885 if (PyErr_Occurred()) {
886 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
887 goto error;
888 PyErr_Clear();
889 }
890 break;
891 }
892
893 /* Interpret it as an int (__index__) */
Georg Brandl3e758462008-07-16 23:10:05 +0000894 rc = _getbytevalue(item, &value);
Christian Heimes44720832008-05-26 13:01:01 +0000895 Py_DECREF(item);
Georg Brandl3e758462008-07-16 23:10:05 +0000896 if (!rc)
Christian Heimes44720832008-05-26 13:01:01 +0000897 goto error;
898
Christian Heimes44720832008-05-26 13:01:01 +0000899 /* Append the byte */
900 if (Py_SIZE(self) < self->ob_alloc)
901 Py_SIZE(self)++;
902 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
903 goto error;
904 self->ob_bytes[Py_SIZE(self)-1] = value;
905 }
906
907 /* Clean up and return success */
908 Py_DECREF(it);
909 return 0;
910
911 error:
912 /* Error handling when it != NULL */
913 Py_DECREF(it);
914 return -1;
915}
916
917/* Mostly copied from string_repr, but without the
918 "smart quote" functionality. */
919static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000920bytearray_repr(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000921{
922 static const char *hexdigits = "0123456789abcdef";
923 const char *quote_prefix = "bytearray(b";
924 const char *quote_postfix = ")";
925 Py_ssize_t length = Py_SIZE(self);
926 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000927 size_t newsize;
Christian Heimes44720832008-05-26 13:01:01 +0000928 PyObject *v;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000929 if (length > (PY_SSIZE_T_MAX - 14) / 4) {
Christian Heimes44720832008-05-26 13:01:01 +0000930 PyErr_SetString(PyExc_OverflowError,
931 "bytearray object is too large to make repr");
932 return NULL;
933 }
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000934 newsize = 14 + 4 * length;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000935 v = PyString_FromStringAndSize(NULL, newsize);
Christian Heimes44720832008-05-26 13:01:01 +0000936 if (v == NULL) {
937 return NULL;
938 }
939 else {
940 register Py_ssize_t i;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000941 register char c;
942 register char *p;
Christian Heimes44720832008-05-26 13:01:01 +0000943 int quote;
944
945 /* Figure out which quote to use; single is preferred */
946 quote = '\'';
947 {
948 char *test, *start;
949 start = PyByteArray_AS_STRING(self);
950 for (test = start; test < start+length; ++test) {
951 if (*test == '"') {
952 quote = '\''; /* back to single */
953 goto decided;
954 }
955 else if (*test == '\'')
956 quote = '"';
957 }
958 decided:
959 ;
960 }
961
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000962 p = PyString_AS_STRING(v);
Christian Heimes44720832008-05-26 13:01:01 +0000963 while (*quote_prefix)
964 *p++ = *quote_prefix++;
965 *p++ = quote;
966
967 for (i = 0; i < length; i++) {
968 /* There's at least enough room for a hex escape
969 and a closing quote. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000970 assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
Christian Heimes44720832008-05-26 13:01:01 +0000971 c = self->ob_bytes[i];
972 if (c == '\'' || c == '\\')
973 *p++ = '\\', *p++ = c;
974 else if (c == '\t')
975 *p++ = '\\', *p++ = 't';
976 else if (c == '\n')
977 *p++ = '\\', *p++ = 'n';
978 else if (c == '\r')
979 *p++ = '\\', *p++ = 'r';
980 else if (c == 0)
981 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
982 else if (c < ' ' || c >= 0x7f) {
983 *p++ = '\\';
984 *p++ = 'x';
985 *p++ = hexdigits[(c & 0xf0) >> 4];
986 *p++ = hexdigits[c & 0xf];
987 }
988 else
989 *p++ = c;
990 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000991 assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
Christian Heimes44720832008-05-26 13:01:01 +0000992 *p++ = quote;
993 while (*quote_postfix) {
994 *p++ = *quote_postfix++;
995 }
996 *p = '\0';
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000997 if (_PyString_Resize(&v, (p - PyString_AS_STRING(v)))) {
Christian Heimes44720832008-05-26 13:01:01 +0000998 Py_DECREF(v);
999 return NULL;
1000 }
1001 return v;
1002 }
1003}
1004
1005static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001006bytearray_str(PyObject *op)
Christian Heimes44720832008-05-26 13:01:01 +00001007{
1008#if 0
1009 if (Py_BytesWarningFlag) {
1010 if (PyErr_WarnEx(PyExc_BytesWarning,
1011 "str() on a bytearray instance", 1))
1012 return NULL;
1013 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001014 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes44720832008-05-26 13:01:01 +00001015#endif
1016 return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
1017}
1018
1019static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001020bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes44720832008-05-26 13:01:01 +00001021{
1022 Py_ssize_t self_size, other_size;
1023 Py_buffer self_bytes, other_bytes;
1024 PyObject *res;
1025 Py_ssize_t minsize;
1026 int cmp;
1027
1028 /* Bytes can be compared to anything that supports the (binary)
1029 buffer API. Except that a comparison with Unicode is always an
1030 error, even if the comparison is for equality. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001031#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00001032 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1033 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
1034 if (Py_BytesWarningFlag && op == Py_EQ) {
1035 if (PyErr_WarnEx(PyExc_BytesWarning,
Ezio Melottid2342082010-01-14 11:34:10 +00001036 "Comparison between bytearray and string", 1))
Christian Heimes44720832008-05-26 13:01:01 +00001037 return NULL;
1038 }
1039
1040 Py_INCREF(Py_NotImplemented);
1041 return Py_NotImplemented;
1042 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001043#endif
Christian Heimes44720832008-05-26 13:01:01 +00001044
1045 self_size = _getbuffer(self, &self_bytes);
1046 if (self_size < 0) {
1047 PyErr_Clear();
1048 Py_INCREF(Py_NotImplemented);
1049 return Py_NotImplemented;
1050 }
1051
1052 other_size = _getbuffer(other, &other_bytes);
1053 if (other_size < 0) {
1054 PyErr_Clear();
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001055 PyBuffer_Release(&self_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001056 Py_INCREF(Py_NotImplemented);
1057 return Py_NotImplemented;
1058 }
1059
1060 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1061 /* Shortcut: if the lengths differ, the objects differ */
1062 cmp = (op == Py_NE);
1063 }
1064 else {
1065 minsize = self_size;
1066 if (other_size < minsize)
1067 minsize = other_size;
1068
1069 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1070 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1071
1072 if (cmp == 0) {
1073 if (self_size < other_size)
1074 cmp = -1;
1075 else if (self_size > other_size)
1076 cmp = 1;
1077 }
1078
1079 switch (op) {
1080 case Py_LT: cmp = cmp < 0; break;
1081 case Py_LE: cmp = cmp <= 0; break;
1082 case Py_EQ: cmp = cmp == 0; break;
1083 case Py_NE: cmp = cmp != 0; break;
1084 case Py_GT: cmp = cmp > 0; break;
1085 case Py_GE: cmp = cmp >= 0; break;
1086 }
1087 }
1088
1089 res = cmp ? Py_True : Py_False;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001090 PyBuffer_Release(&self_bytes);
1091 PyBuffer_Release(&other_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001092 Py_INCREF(res);
1093 return res;
1094}
1095
1096static void
Benjamin Petersond6720012009-04-18 15:31:34 +00001097bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00001098{
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001099 if (self->ob_exports > 0) {
1100 PyErr_SetString(PyExc_SystemError,
Georg Brandl517cfdc2009-04-05 13:16:35 +00001101 "deallocated bytearray object has exported buffers");
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001102 PyErr_Print();
1103 }
Christian Heimes44720832008-05-26 13:01:01 +00001104 if (self->ob_bytes != 0) {
1105 PyMem_Free(self->ob_bytes);
1106 }
1107 Py_TYPE(self)->tp_free((PyObject *)self);
1108}
1109
1110
1111/* -------------------------------------------------------------------- */
1112/* Methods */
1113
1114#define STRINGLIB_CHAR char
Christian Heimes44720832008-05-26 13:01:01 +00001115#define STRINGLIB_LEN PyByteArray_GET_SIZE
1116#define STRINGLIB_STR PyByteArray_AS_STRING
1117#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrou64672132010-01-13 07:55:48 +00001118#define STRINGLIB_ISSPACE Py_ISSPACE
1119#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes44720832008-05-26 13:01:01 +00001120#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1121#define STRINGLIB_MUTABLE 1
1122
1123#include "stringlib/fastsearch.h"
1124#include "stringlib/count.h"
1125#include "stringlib/find.h"
1126#include "stringlib/partition.h"
Antoine Pitrou64672132010-01-13 07:55:48 +00001127#include "stringlib/split.h"
Christian Heimes44720832008-05-26 13:01:01 +00001128#include "stringlib/ctype.h"
1129#include "stringlib/transmogrify.h"
1130
1131
1132/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1133were copied from the old char* style string object. */
1134
Antoine Pitrou64672132010-01-13 07:55:48 +00001135/* helper macro to fixup start/end slice values */
1136#define ADJUST_INDICES(start, end, len) \
1137 if (end > len) \
1138 end = len; \
1139 else if (end < 0) { \
1140 end += len; \
1141 if (end < 0) \
1142 end = 0; \
1143 } \
1144 if (start < 0) { \
1145 start += len; \
1146 if (start < 0) \
1147 start = 0; \
1148 }
Christian Heimes44720832008-05-26 13:01:01 +00001149
1150Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Petersond6720012009-04-18 15:31:34 +00001151bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes44720832008-05-26 13:01:01 +00001152{
1153 PyObject *subobj;
1154 Py_buffer subbuf;
1155 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1156 Py_ssize_t res;
1157
Jesus Cea44e81682011-04-20 16:39:15 +02001158 if (!stringlib_parse_args_finds("find/rfind/index/rindex",
1159 args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001160 return -2;
1161 if (_getbuffer(subobj, &subbuf) < 0)
1162 return -2;
1163 if (dir > 0)
1164 res = stringlib_find_slice(
1165 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1166 subbuf.buf, subbuf.len, start, end);
1167 else
1168 res = stringlib_rfind_slice(
1169 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1170 subbuf.buf, subbuf.len, start, end);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001171 PyBuffer_Release(&subbuf);
Christian Heimes44720832008-05-26 13:01:01 +00001172 return res;
1173}
1174
1175PyDoc_STRVAR(find__doc__,
1176"B.find(sub [,start [,end]]) -> int\n\
1177\n\
1178Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran5e3a19d2011-07-27 23:36:51 +08001179such that sub is contained within B[start,end]. Optional\n\
Christian Heimes44720832008-05-26 13:01:01 +00001180arguments start and end are interpreted as in slice notation.\n\
1181\n\
1182Return -1 on failure.");
1183
1184static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001185bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001186{
Benjamin Petersond6720012009-04-18 15:31:34 +00001187 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001188 if (result == -2)
1189 return NULL;
1190 return PyInt_FromSsize_t(result);
1191}
1192
1193PyDoc_STRVAR(count__doc__,
1194"B.count(sub [,start [,end]]) -> int\n\
1195\n\
1196Return the number of non-overlapping occurrences of subsection sub in\n\
1197bytes B[start:end]. Optional arguments start and end are interpreted\n\
1198as in slice notation.");
1199
1200static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001201bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001202{
1203 PyObject *sub_obj;
1204 const char *str = PyByteArray_AS_STRING(self);
1205 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1206 Py_buffer vsub;
1207 PyObject *count_obj;
1208
Jesus Cea44e81682011-04-20 16:39:15 +02001209 if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001210 return NULL;
1211
1212 if (_getbuffer(sub_obj, &vsub) < 0)
1213 return NULL;
1214
Antoine Pitrou64672132010-01-13 07:55:48 +00001215 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes44720832008-05-26 13:01:01 +00001216
1217 count_obj = PyInt_FromSsize_t(
Antoine Pitrou64672132010-01-13 07:55:48 +00001218 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes44720832008-05-26 13:01:01 +00001219 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001220 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00001221 return count_obj;
1222}
1223
1224
1225PyDoc_STRVAR(index__doc__,
1226"B.index(sub [,start [,end]]) -> int\n\
1227\n\
1228Like B.find() but raise ValueError when the subsection is not found.");
1229
1230static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001231bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001232{
Benjamin Petersond6720012009-04-18 15:31:34 +00001233 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001234 if (result == -2)
1235 return NULL;
1236 if (result == -1) {
1237 PyErr_SetString(PyExc_ValueError,
1238 "subsection not found");
1239 return NULL;
1240 }
1241 return PyInt_FromSsize_t(result);
1242}
1243
1244
1245PyDoc_STRVAR(rfind__doc__,
1246"B.rfind(sub [,start [,end]]) -> int\n\
1247\n\
1248Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran5e3a19d2011-07-27 23:36:51 +08001249such that sub is contained within B[start,end]. Optional\n\
Christian Heimes44720832008-05-26 13:01:01 +00001250arguments start and end are interpreted as in slice notation.\n\
1251\n\
1252Return -1 on failure.");
1253
1254static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001255bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001256{
Benjamin Petersond6720012009-04-18 15:31:34 +00001257 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001258 if (result == -2)
1259 return NULL;
1260 return PyInt_FromSsize_t(result);
1261}
1262
1263
1264PyDoc_STRVAR(rindex__doc__,
1265"B.rindex(sub [,start [,end]]) -> int\n\
1266\n\
1267Like B.rfind() but raise ValueError when the subsection is not found.");
1268
1269static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001270bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001271{
Benjamin Petersond6720012009-04-18 15:31:34 +00001272 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001273 if (result == -2)
1274 return NULL;
1275 if (result == -1) {
1276 PyErr_SetString(PyExc_ValueError,
1277 "subsection not found");
1278 return NULL;
1279 }
1280 return PyInt_FromSsize_t(result);
1281}
1282
1283
1284static int
Benjamin Petersond6720012009-04-18 15:31:34 +00001285bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00001286{
1287 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1288 if (ival == -1 && PyErr_Occurred()) {
1289 Py_buffer varg;
1290 int pos;
1291 PyErr_Clear();
1292 if (_getbuffer(arg, &varg) < 0)
1293 return -1;
1294 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1295 varg.buf, varg.len, 0);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001296 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00001297 return pos >= 0;
1298 }
1299 if (ival < 0 || ival >= 256) {
1300 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1301 return -1;
1302 }
1303
1304 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1305}
1306
1307
1308/* Matches the end (direction >= 0) or start (direction < 0) of self
1309 * against substr, using the start and end arguments. Returns
1310 * -1 on error, 0 if not found and 1 if found.
1311 */
1312Py_LOCAL(int)
Benjamin Petersond6720012009-04-18 15:31:34 +00001313_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes44720832008-05-26 13:01:01 +00001314 Py_ssize_t end, int direction)
1315{
1316 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1317 const char* str;
1318 Py_buffer vsubstr;
1319 int rv = 0;
1320
1321 str = PyByteArray_AS_STRING(self);
1322
1323 if (_getbuffer(substr, &vsubstr) < 0)
1324 return -1;
1325
Antoine Pitrou64672132010-01-13 07:55:48 +00001326 ADJUST_INDICES(start, end, len);
Christian Heimes44720832008-05-26 13:01:01 +00001327
1328 if (direction < 0) {
1329 /* startswith */
1330 if (start+vsubstr.len > len) {
1331 goto done;
1332 }
1333 } else {
1334 /* endswith */
1335 if (end-start < vsubstr.len || start > len) {
1336 goto done;
1337 }
1338
1339 if (end-vsubstr.len > start)
1340 start = end - vsubstr.len;
1341 }
1342 if (end-start >= vsubstr.len)
1343 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1344
1345done:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001346 PyBuffer_Release(&vsubstr);
Christian Heimes44720832008-05-26 13:01:01 +00001347 return rv;
1348}
1349
1350
1351PyDoc_STRVAR(startswith__doc__,
1352"B.startswith(prefix [,start [,end]]) -> bool\n\
1353\n\
1354Return True if B starts with the specified prefix, False otherwise.\n\
1355With optional start, test B beginning at that position.\n\
1356With optional end, stop comparing B at that position.\n\
1357prefix can also be a tuple of strings to try.");
1358
1359static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001360bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001361{
1362 Py_ssize_t start = 0;
1363 Py_ssize_t end = PY_SSIZE_T_MAX;
1364 PyObject *subobj;
1365 int result;
1366
Jesus Cea44e81682011-04-20 16:39:15 +02001367 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001368 return NULL;
1369 if (PyTuple_Check(subobj)) {
1370 Py_ssize_t i;
1371 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001372 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001373 PyTuple_GET_ITEM(subobj, i),
1374 start, end, -1);
1375 if (result == -1)
1376 return NULL;
1377 else if (result) {
1378 Py_RETURN_TRUE;
1379 }
1380 }
1381 Py_RETURN_FALSE;
1382 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001383 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001384 if (result == -1)
1385 return NULL;
1386 else
1387 return PyBool_FromLong(result);
1388}
1389
1390PyDoc_STRVAR(endswith__doc__,
1391"B.endswith(suffix [,start [,end]]) -> bool\n\
1392\n\
1393Return True if B ends with the specified suffix, False otherwise.\n\
1394With optional start, test B beginning at that position.\n\
1395With optional end, stop comparing B at that position.\n\
1396suffix can also be a tuple of strings to try.");
1397
1398static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001399bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001400{
1401 Py_ssize_t start = 0;
1402 Py_ssize_t end = PY_SSIZE_T_MAX;
1403 PyObject *subobj;
1404 int result;
1405
Jesus Cea44e81682011-04-20 16:39:15 +02001406 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001407 return NULL;
1408 if (PyTuple_Check(subobj)) {
1409 Py_ssize_t i;
1410 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001411 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001412 PyTuple_GET_ITEM(subobj, i),
1413 start, end, +1);
1414 if (result == -1)
1415 return NULL;
1416 else if (result) {
1417 Py_RETURN_TRUE;
1418 }
1419 }
1420 Py_RETURN_FALSE;
1421 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001422 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001423 if (result == -1)
1424 return NULL;
1425 else
1426 return PyBool_FromLong(result);
1427}
1428
1429
1430PyDoc_STRVAR(translate__doc__,
1431"B.translate(table[, deletechars]) -> bytearray\n\
1432\n\
1433Return a copy of B, where all characters occurring in the\n\
1434optional argument deletechars are removed, and the remaining\n\
1435characters have been mapped through the given translation\n\
1436table, which must be a bytes object of length 256.");
1437
1438static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001439bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001440{
1441 register char *input, *output;
1442 register const char *table;
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001443 register Py_ssize_t i, c;
Christian Heimes44720832008-05-26 13:01:01 +00001444 PyObject *input_obj = (PyObject*)self;
1445 const char *output_start;
1446 Py_ssize_t inlen;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001447 PyObject *result = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001448 int trans_table[256];
Georg Brandl6425a2f2008-12-28 11:54:53 +00001449 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001450 Py_buffer vtable, vdel;
1451
1452 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1453 &tableobj, &delobj))
1454 return NULL;
1455
Georg Brandl6425a2f2008-12-28 11:54:53 +00001456 if (tableobj == Py_None) {
1457 table = NULL;
1458 tableobj = NULL;
1459 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00001460 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001461 } else {
1462 if (vtable.len != 256) {
1463 PyErr_SetString(PyExc_ValueError,
1464 "translation table must be 256 characters long");
Georg Brandlec812ca2009-07-22 11:57:15 +00001465 PyBuffer_Release(&vtable);
1466 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001467 }
1468 table = (const char*)vtable.buf;
Christian Heimes44720832008-05-26 13:01:01 +00001469 }
1470
1471 if (delobj != NULL) {
1472 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandlec812ca2009-07-22 11:57:15 +00001473 if (tableobj != NULL)
1474 PyBuffer_Release(&vtable);
1475 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001476 }
1477 }
1478 else {
1479 vdel.buf = NULL;
1480 vdel.len = 0;
1481 }
1482
Christian Heimes44720832008-05-26 13:01:01 +00001483 inlen = PyByteArray_GET_SIZE(input_obj);
1484 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1485 if (result == NULL)
1486 goto done;
1487 output_start = output = PyByteArray_AsString(result);
1488 input = PyByteArray_AS_STRING(input_obj);
1489
Georg Brandl6425a2f2008-12-28 11:54:53 +00001490 if (vdel.len == 0 && table != NULL) {
Christian Heimes44720832008-05-26 13:01:01 +00001491 /* If no deletions are required, use faster code */
1492 for (i = inlen; --i >= 0; ) {
1493 c = Py_CHARMASK(*input++);
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001494 *output++ = table[c];
Christian Heimes44720832008-05-26 13:01:01 +00001495 }
Christian Heimes44720832008-05-26 13:01:01 +00001496 goto done;
1497 }
Georg Brandl6425a2f2008-12-28 11:54:53 +00001498
1499 if (table == NULL) {
1500 for (i = 0; i < 256; i++)
1501 trans_table[i] = Py_CHARMASK(i);
1502 } else {
1503 for (i = 0; i < 256; i++)
1504 trans_table[i] = Py_CHARMASK(table[i]);
1505 }
Christian Heimes44720832008-05-26 13:01:01 +00001506
1507 for (i = 0; i < vdel.len; i++)
1508 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1509
1510 for (i = inlen; --i >= 0; ) {
1511 c = Py_CHARMASK(*input++);
1512 if (trans_table[c] != -1)
1513 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1514 continue;
Christian Heimes44720832008-05-26 13:01:01 +00001515 }
1516 /* Fix the size of the resulting string */
1517 if (inlen > 0)
1518 PyByteArray_Resize(result, output - output_start);
1519
1520done:
Georg Brandl6425a2f2008-12-28 11:54:53 +00001521 if (tableobj != NULL)
1522 PyBuffer_Release(&vtable);
Christian Heimes44720832008-05-26 13:01:01 +00001523 if (delobj != NULL)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001524 PyBuffer_Release(&vdel);
Christian Heimes44720832008-05-26 13:01:01 +00001525 return result;
1526}
1527
1528
Christian Heimes44720832008-05-26 13:01:01 +00001529/* find and count characters and substrings */
1530
1531#define findchar(target, target_len, c) \
1532 ((char *)memchr((const void *)(target), c, target_len))
1533
Christian Heimes44720832008-05-26 13:01:01 +00001534
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001535/* Bytes ops must return a string, create a copy */
Christian Heimes44720832008-05-26 13:01:01 +00001536Py_LOCAL(PyByteArrayObject *)
1537return_self(PyByteArrayObject *self)
1538{
Christian Heimes44720832008-05-26 13:01:01 +00001539 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1540 PyByteArray_AS_STRING(self),
1541 PyByteArray_GET_SIZE(self));
1542}
1543
1544Py_LOCAL_INLINE(Py_ssize_t)
1545countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1546{
1547 Py_ssize_t count=0;
1548 const char *start=target;
1549 const char *end=target+target_len;
1550
1551 while ( (start=findchar(start, end-start, c)) != NULL ) {
1552 count++;
1553 if (count >= maxcount)
1554 break;
1555 start += 1;
1556 }
1557 return count;
1558}
1559
Christian Heimes44720832008-05-26 13:01:01 +00001560
1561/* Algorithms for different cases of string replacement */
1562
1563/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1564Py_LOCAL(PyByteArrayObject *)
1565replace_interleave(PyByteArrayObject *self,
1566 const char *to_s, Py_ssize_t to_len,
1567 Py_ssize_t maxcount)
1568{
1569 char *self_s, *result_s;
1570 Py_ssize_t self_len, result_len;
1571 Py_ssize_t count, i, product;
1572 PyByteArrayObject *result;
1573
1574 self_len = PyByteArray_GET_SIZE(self);
1575
1576 /* 1 at the end plus 1 after every character */
1577 count = self_len+1;
1578 if (maxcount < count)
1579 count = maxcount;
1580
1581 /* Check for overflow */
1582 /* result_len = count * to_len + self_len; */
1583 product = count * to_len;
1584 if (product / to_len != count) {
1585 PyErr_SetString(PyExc_OverflowError,
1586 "replace string is too long");
1587 return NULL;
1588 }
1589 result_len = product + self_len;
1590 if (result_len < 0) {
1591 PyErr_SetString(PyExc_OverflowError,
1592 "replace string is too long");
1593 return NULL;
1594 }
1595
1596 if (! (result = (PyByteArrayObject *)
1597 PyByteArray_FromStringAndSize(NULL, result_len)) )
1598 return NULL;
1599
1600 self_s = PyByteArray_AS_STRING(self);
1601 result_s = PyByteArray_AS_STRING(result);
1602
1603 /* TODO: special case single character, which doesn't need memcpy */
1604
1605 /* Lay the first one down (guaranteed this will occur) */
1606 Py_MEMCPY(result_s, to_s, to_len);
1607 result_s += to_len;
1608 count -= 1;
1609
1610 for (i=0; i<count; i++) {
1611 *result_s++ = *self_s++;
1612 Py_MEMCPY(result_s, to_s, to_len);
1613 result_s += to_len;
1614 }
1615
1616 /* Copy the rest of the original string */
1617 Py_MEMCPY(result_s, self_s, self_len-i);
1618
1619 return result;
1620}
1621
1622/* Special case for deleting a single character */
1623/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1624Py_LOCAL(PyByteArrayObject *)
1625replace_delete_single_character(PyByteArrayObject *self,
1626 char from_c, Py_ssize_t maxcount)
1627{
1628 char *self_s, *result_s;
1629 char *start, *next, *end;
1630 Py_ssize_t self_len, result_len;
1631 Py_ssize_t count;
1632 PyByteArrayObject *result;
1633
1634 self_len = PyByteArray_GET_SIZE(self);
1635 self_s = PyByteArray_AS_STRING(self);
1636
1637 count = countchar(self_s, self_len, from_c, maxcount);
1638 if (count == 0) {
1639 return return_self(self);
1640 }
1641
1642 result_len = self_len - count; /* from_len == 1 */
1643 assert(result_len>=0);
1644
1645 if ( (result = (PyByteArrayObject *)
1646 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1647 return NULL;
1648 result_s = PyByteArray_AS_STRING(result);
1649
1650 start = self_s;
1651 end = self_s + self_len;
1652 while (count-- > 0) {
1653 next = findchar(start, end-start, from_c);
1654 if (next == NULL)
1655 break;
1656 Py_MEMCPY(result_s, start, next-start);
1657 result_s += (next-start);
1658 start = next+1;
1659 }
1660 Py_MEMCPY(result_s, start, end-start);
1661
1662 return result;
1663}
1664
1665/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1666
1667Py_LOCAL(PyByteArrayObject *)
1668replace_delete_substring(PyByteArrayObject *self,
1669 const char *from_s, Py_ssize_t from_len,
1670 Py_ssize_t maxcount)
1671{
1672 char *self_s, *result_s;
1673 char *start, *next, *end;
1674 Py_ssize_t self_len, result_len;
1675 Py_ssize_t count, offset;
1676 PyByteArrayObject *result;
1677
1678 self_len = PyByteArray_GET_SIZE(self);
1679 self_s = PyByteArray_AS_STRING(self);
1680
Antoine Pitrou64672132010-01-13 07:55:48 +00001681 count = stringlib_count(self_s, self_len,
1682 from_s, from_len,
1683 maxcount);
Christian Heimes44720832008-05-26 13:01:01 +00001684
1685 if (count == 0) {
1686 /* no matches */
1687 return return_self(self);
1688 }
1689
1690 result_len = self_len - (count * from_len);
1691 assert (result_len>=0);
1692
1693 if ( (result = (PyByteArrayObject *)
1694 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1695 return NULL;
1696
1697 result_s = PyByteArray_AS_STRING(result);
1698
1699 start = self_s;
1700 end = self_s + self_len;
1701 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001702 offset = stringlib_find(start, end-start,
1703 from_s, from_len,
1704 0);
Christian Heimes44720832008-05-26 13:01:01 +00001705 if (offset == -1)
1706 break;
1707 next = start + offset;
1708
1709 Py_MEMCPY(result_s, start, next-start);
1710
1711 result_s += (next-start);
1712 start = next+from_len;
1713 }
1714 Py_MEMCPY(result_s, start, end-start);
1715 return result;
1716}
1717
1718/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1719Py_LOCAL(PyByteArrayObject *)
1720replace_single_character_in_place(PyByteArrayObject *self,
1721 char from_c, char to_c,
1722 Py_ssize_t maxcount)
1723{
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001724 char *self_s, *result_s, *start, *end, *next;
1725 Py_ssize_t self_len;
1726 PyByteArrayObject *result;
Christian Heimes44720832008-05-26 13:01:01 +00001727
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001728 /* The result string will be the same size */
1729 self_s = PyByteArray_AS_STRING(self);
1730 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes44720832008-05-26 13:01:01 +00001731
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001732 next = findchar(self_s, self_len, from_c);
Christian Heimes44720832008-05-26 13:01:01 +00001733
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001734 if (next == NULL) {
1735 /* No matches; return the original bytes */
1736 return return_self(self);
1737 }
Christian Heimes44720832008-05-26 13:01:01 +00001738
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001739 /* Need to make a new bytes */
1740 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1741 if (result == NULL)
1742 return NULL;
1743 result_s = PyByteArray_AS_STRING(result);
1744 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes44720832008-05-26 13:01:01 +00001745
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001746 /* change everything in-place, starting with this one */
1747 start = result_s + (next-self_s);
1748 *start = to_c;
1749 start++;
1750 end = result_s + self_len;
Christian Heimes44720832008-05-26 13:01:01 +00001751
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001752 while (--maxcount > 0) {
1753 next = findchar(start, end-start, from_c);
1754 if (next == NULL)
1755 break;
1756 *next = to_c;
1757 start = next+1;
1758 }
Christian Heimes44720832008-05-26 13:01:01 +00001759
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001760 return result;
Christian Heimes44720832008-05-26 13:01:01 +00001761}
1762
1763/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1764Py_LOCAL(PyByteArrayObject *)
1765replace_substring_in_place(PyByteArrayObject *self,
1766 const char *from_s, Py_ssize_t from_len,
1767 const char *to_s, Py_ssize_t to_len,
1768 Py_ssize_t maxcount)
1769{
1770 char *result_s, *start, *end;
1771 char *self_s;
1772 Py_ssize_t self_len, offset;
1773 PyByteArrayObject *result;
1774
1775 /* The result bytes will be the same size */
1776
1777 self_s = PyByteArray_AS_STRING(self);
1778 self_len = PyByteArray_GET_SIZE(self);
1779
Antoine Pitrou64672132010-01-13 07:55:48 +00001780 offset = stringlib_find(self_s, self_len,
1781 from_s, from_len,
1782 0);
Christian Heimes44720832008-05-26 13:01:01 +00001783 if (offset == -1) {
1784 /* No matches; return the original bytes */
1785 return return_self(self);
1786 }
1787
1788 /* Need to make a new bytes */
1789 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1790 if (result == NULL)
1791 return NULL;
1792 result_s = PyByteArray_AS_STRING(result);
1793 Py_MEMCPY(result_s, self_s, self_len);
1794
1795 /* change everything in-place, starting with this one */
1796 start = result_s + offset;
1797 Py_MEMCPY(start, to_s, from_len);
1798 start += from_len;
1799 end = result_s + self_len;
1800
1801 while ( --maxcount > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001802 offset = stringlib_find(start, end-start,
1803 from_s, from_len,
1804 0);
Christian Heimes44720832008-05-26 13:01:01 +00001805 if (offset==-1)
1806 break;
1807 Py_MEMCPY(start+offset, to_s, from_len);
1808 start += offset+from_len;
1809 }
1810
1811 return result;
1812}
1813
1814/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1815Py_LOCAL(PyByteArrayObject *)
1816replace_single_character(PyByteArrayObject *self,
1817 char from_c,
1818 const char *to_s, Py_ssize_t to_len,
1819 Py_ssize_t maxcount)
1820{
1821 char *self_s, *result_s;
1822 char *start, *next, *end;
1823 Py_ssize_t self_len, result_len;
1824 Py_ssize_t count, product;
1825 PyByteArrayObject *result;
1826
1827 self_s = PyByteArray_AS_STRING(self);
1828 self_len = PyByteArray_GET_SIZE(self);
1829
1830 count = countchar(self_s, self_len, from_c, maxcount);
1831 if (count == 0) {
1832 /* no matches, return unchanged */
1833 return return_self(self);
1834 }
1835
1836 /* use the difference between current and new, hence the "-1" */
1837 /* result_len = self_len + count * (to_len-1) */
1838 product = count * (to_len-1);
1839 if (product / (to_len-1) != count) {
1840 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1841 return NULL;
1842 }
1843 result_len = self_len + product;
1844 if (result_len < 0) {
1845 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1846 return NULL;
1847 }
1848
1849 if ( (result = (PyByteArrayObject *)
1850 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1851 return NULL;
1852 result_s = PyByteArray_AS_STRING(result);
1853
1854 start = self_s;
1855 end = self_s + self_len;
1856 while (count-- > 0) {
1857 next = findchar(start, end-start, from_c);
1858 if (next == NULL)
1859 break;
1860
1861 if (next == start) {
1862 /* replace with the 'to' */
1863 Py_MEMCPY(result_s, to_s, to_len);
1864 result_s += to_len;
1865 start += 1;
1866 } else {
1867 /* copy the unchanged old then the 'to' */
1868 Py_MEMCPY(result_s, start, next-start);
1869 result_s += (next-start);
1870 Py_MEMCPY(result_s, to_s, to_len);
1871 result_s += to_len;
1872 start = next+1;
1873 }
1874 }
1875 /* Copy the remainder of the remaining bytes */
1876 Py_MEMCPY(result_s, start, end-start);
1877
1878 return result;
1879}
1880
1881/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1882Py_LOCAL(PyByteArrayObject *)
1883replace_substring(PyByteArrayObject *self,
1884 const char *from_s, Py_ssize_t from_len,
1885 const char *to_s, Py_ssize_t to_len,
1886 Py_ssize_t maxcount)
1887{
1888 char *self_s, *result_s;
1889 char *start, *next, *end;
1890 Py_ssize_t self_len, result_len;
1891 Py_ssize_t count, offset, product;
1892 PyByteArrayObject *result;
1893
1894 self_s = PyByteArray_AS_STRING(self);
1895 self_len = PyByteArray_GET_SIZE(self);
1896
Antoine Pitrou64672132010-01-13 07:55:48 +00001897 count = stringlib_count(self_s, self_len,
1898 from_s, from_len,
1899 maxcount);
1900
Christian Heimes44720832008-05-26 13:01:01 +00001901 if (count == 0) {
1902 /* no matches, return unchanged */
1903 return return_self(self);
1904 }
1905
1906 /* Check for overflow */
1907 /* result_len = self_len + count * (to_len-from_len) */
1908 product = count * (to_len-from_len);
1909 if (product / (to_len-from_len) != count) {
1910 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1911 return NULL;
1912 }
1913 result_len = self_len + product;
1914 if (result_len < 0) {
1915 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1916 return NULL;
1917 }
1918
1919 if ( (result = (PyByteArrayObject *)
1920 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1921 return NULL;
1922 result_s = PyByteArray_AS_STRING(result);
1923
1924 start = self_s;
1925 end = self_s + self_len;
1926 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001927 offset = stringlib_find(start, end-start,
1928 from_s, from_len,
1929 0);
Christian Heimes44720832008-05-26 13:01:01 +00001930 if (offset == -1)
1931 break;
1932 next = start+offset;
1933 if (next == start) {
1934 /* replace with the 'to' */
1935 Py_MEMCPY(result_s, to_s, to_len);
1936 result_s += to_len;
1937 start += from_len;
1938 } else {
1939 /* copy the unchanged old then the 'to' */
1940 Py_MEMCPY(result_s, start, next-start);
1941 result_s += (next-start);
1942 Py_MEMCPY(result_s, to_s, to_len);
1943 result_s += to_len;
1944 start = next+from_len;
1945 }
1946 }
1947 /* Copy the remainder of the remaining bytes */
1948 Py_MEMCPY(result_s, start, end-start);
1949
1950 return result;
1951}
1952
1953
1954Py_LOCAL(PyByteArrayObject *)
1955replace(PyByteArrayObject *self,
1956 const char *from_s, Py_ssize_t from_len,
1957 const char *to_s, Py_ssize_t to_len,
1958 Py_ssize_t maxcount)
1959{
1960 if (maxcount < 0) {
1961 maxcount = PY_SSIZE_T_MAX;
1962 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1963 /* nothing to do; return the original bytes */
1964 return return_self(self);
1965 }
1966
1967 if (maxcount == 0 ||
1968 (from_len == 0 && to_len == 0)) {
1969 /* nothing to do; return the original bytes */
1970 return return_self(self);
1971 }
1972
1973 /* Handle zero-length special cases */
1974
1975 if (from_len == 0) {
1976 /* insert the 'to' bytes everywhere. */
1977 /* >>> "Python".replace("", ".") */
1978 /* '.P.y.t.h.o.n.' */
1979 return replace_interleave(self, to_s, to_len, maxcount);
1980 }
1981
1982 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1983 /* point for an empty self bytes to generate a non-empty bytes */
1984 /* Special case so the remaining code always gets a non-empty bytes */
1985 if (PyByteArray_GET_SIZE(self) == 0) {
1986 return return_self(self);
1987 }
1988
1989 if (to_len == 0) {
1990 /* delete all occurances of 'from' bytes */
1991 if (from_len == 1) {
1992 return replace_delete_single_character(
1993 self, from_s[0], maxcount);
1994 } else {
1995 return replace_delete_substring(self, from_s, from_len, maxcount);
1996 }
1997 }
1998
1999 /* Handle special case where both bytes have the same length */
2000
2001 if (from_len == to_len) {
2002 if (from_len == 1) {
2003 return replace_single_character_in_place(
2004 self,
2005 from_s[0],
2006 to_s[0],
2007 maxcount);
2008 } else {
2009 return replace_substring_in_place(
2010 self, from_s, from_len, to_s, to_len, maxcount);
2011 }
2012 }
2013
2014 /* Otherwise use the more generic algorithms */
2015 if (from_len == 1) {
2016 return replace_single_character(self, from_s[0],
2017 to_s, to_len, maxcount);
2018 } else {
2019 /* len('from')>=2, len('to')>=1 */
2020 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2021 }
2022}
2023
2024
2025PyDoc_STRVAR(replace__doc__,
2026"B.replace(old, new[, count]) -> bytes\n\
2027\n\
2028Return a copy of B with all occurrences of subsection\n\
2029old replaced by new. If the optional argument count is\n\
2030given, only the first count occurrences are replaced.");
2031
2032static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002033bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002034{
2035 Py_ssize_t count = -1;
2036 PyObject *from, *to, *res;
2037 Py_buffer vfrom, vto;
2038
2039 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2040 return NULL;
2041
2042 if (_getbuffer(from, &vfrom) < 0)
2043 return NULL;
2044 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002045 PyBuffer_Release(&vfrom);
Christian Heimes44720832008-05-26 13:01:01 +00002046 return NULL;
2047 }
2048
2049 res = (PyObject *)replace((PyByteArrayObject *) self,
2050 vfrom.buf, vfrom.len,
2051 vto.buf, vto.len, count);
2052
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002053 PyBuffer_Release(&vfrom);
2054 PyBuffer_Release(&vto);
Christian Heimes44720832008-05-26 13:01:01 +00002055 return res;
2056}
2057
Christian Heimes44720832008-05-26 13:01:01 +00002058PyDoc_STRVAR(split__doc__,
2059"B.split([sep[, maxsplit]]) -> list of bytearray\n\
2060\n\
2061Return a list of the sections in B, using sep as the delimiter.\n\
2062If sep is not given, B is split on ASCII whitespace characters\n\
2063(space, tab, return, newline, formfeed, vertical tab).\n\
2064If maxsplit is given, at most maxsplit splits are done.");
2065
2066static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002067bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002068{
Antoine Pitrou64672132010-01-13 07:55:48 +00002069 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2070 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002071 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002072 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002073 Py_buffer vsub;
Christian Heimes44720832008-05-26 13:01:01 +00002074
2075 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2076 return NULL;
2077 if (maxsplit < 0)
2078 maxsplit = PY_SSIZE_T_MAX;
2079
2080 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002081 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002082
2083 if (_getbuffer(subobj, &vsub) < 0)
2084 return NULL;
2085 sub = vsub.buf;
2086 n = vsub.len;
2087
Antoine Pitrou64672132010-01-13 07:55:48 +00002088 list = stringlib_split(
2089 (PyObject*) self, s, len, sub, n, maxsplit
2090 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002091 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002092 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002093}
2094
2095PyDoc_STRVAR(partition__doc__,
2096"B.partition(sep) -> (head, sep, tail)\n\
2097\n\
2098Searches for the separator sep in B, and returns the part before it,\n\
2099the separator itself, and the part after it. If the separator is not\n\
2100found, returns B and two empty bytearray objects.");
2101
2102static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002103bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002104{
2105 PyObject *bytesep, *result;
2106
2107 bytesep = PyByteArray_FromObject(sep_obj);
2108 if (! bytesep)
2109 return NULL;
2110
2111 result = stringlib_partition(
2112 (PyObject*) self,
2113 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2114 bytesep,
2115 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2116 );
2117
2118 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002119 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002120}
2121
2122PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti1fafaab2010-01-25 11:24:37 +00002123"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes44720832008-05-26 13:01:01 +00002124\n\
2125Searches for the separator sep in B, starting at the end of B,\n\
2126and returns the part before it, the separator itself, and the\n\
2127part after it. If the separator is not found, returns two empty\n\
2128bytearray objects and B.");
2129
2130static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002131bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002132{
2133 PyObject *bytesep, *result;
2134
2135 bytesep = PyByteArray_FromObject(sep_obj);
2136 if (! bytesep)
2137 return NULL;
2138
2139 result = stringlib_rpartition(
2140 (PyObject*) self,
2141 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2142 bytesep,
2143 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2144 );
2145
2146 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002147 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002148}
2149
2150PyDoc_STRVAR(rsplit__doc__,
2151"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2152\n\
2153Return a list of the sections in B, using sep as the delimiter,\n\
2154starting at the end of B and working to the front.\n\
2155If sep is not given, B is split on ASCII whitespace characters\n\
2156(space, tab, return, newline, formfeed, vertical tab).\n\
2157If maxsplit is given, at most maxsplit splits are done.");
2158
2159static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002160bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002161{
Antoine Pitrou64672132010-01-13 07:55:48 +00002162 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2163 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002164 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002165 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002166 Py_buffer vsub;
2167
2168 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2169 return NULL;
2170 if (maxsplit < 0)
2171 maxsplit = PY_SSIZE_T_MAX;
2172
2173 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002174 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002175
2176 if (_getbuffer(subobj, &vsub) < 0)
2177 return NULL;
2178 sub = vsub.buf;
2179 n = vsub.len;
2180
Antoine Pitrou64672132010-01-13 07:55:48 +00002181 list = stringlib_rsplit(
2182 (PyObject*) self, s, len, sub, n, maxsplit
2183 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002184 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002185 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002186}
2187
2188PyDoc_STRVAR(reverse__doc__,
2189"B.reverse() -> None\n\
2190\n\
2191Reverse the order of the values in B in place.");
2192static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002193bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes44720832008-05-26 13:01:01 +00002194{
2195 char swap, *head, *tail;
2196 Py_ssize_t i, j, n = Py_SIZE(self);
2197
2198 j = n / 2;
2199 head = self->ob_bytes;
2200 tail = head + n - 1;
2201 for (i = 0; i < j; i++) {
2202 swap = *head;
2203 *head++ = *tail;
2204 *tail-- = swap;
2205 }
2206
2207 Py_RETURN_NONE;
2208}
2209
2210PyDoc_STRVAR(insert__doc__,
2211"B.insert(index, int) -> None\n\
2212\n\
2213Insert a single item into the bytearray before the given index.");
2214static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002215bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002216{
Georg Brandl3e483f62008-07-16 22:57:41 +00002217 PyObject *value;
2218 int ival;
Christian Heimes44720832008-05-26 13:01:01 +00002219 Py_ssize_t where, n = Py_SIZE(self);
2220
Georg Brandl3e483f62008-07-16 22:57:41 +00002221 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes44720832008-05-26 13:01:01 +00002222 return NULL;
2223
2224 if (n == PY_SSIZE_T_MAX) {
2225 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002226 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002227 return NULL;
2228 }
Georg Brandl3e483f62008-07-16 22:57:41 +00002229 if (!_getbytevalue(value, &ival))
Christian Heimes44720832008-05-26 13:01:01 +00002230 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002231 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2232 return NULL;
2233
2234 if (where < 0) {
2235 where += n;
2236 if (where < 0)
2237 where = 0;
2238 }
2239 if (where > n)
2240 where = n;
2241 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl3e483f62008-07-16 22:57:41 +00002242 self->ob_bytes[where] = ival;
Christian Heimes44720832008-05-26 13:01:01 +00002243
2244 Py_RETURN_NONE;
2245}
2246
2247PyDoc_STRVAR(append__doc__,
2248"B.append(int) -> None\n\
2249\n\
2250Append a single item to the end of B.");
2251static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002252bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002253{
2254 int value;
2255 Py_ssize_t n = Py_SIZE(self);
2256
2257 if (! _getbytevalue(arg, &value))
2258 return NULL;
2259 if (n == PY_SSIZE_T_MAX) {
2260 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002261 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002262 return NULL;
2263 }
2264 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2265 return NULL;
2266
2267 self->ob_bytes[n] = value;
2268
2269 Py_RETURN_NONE;
2270}
2271
2272PyDoc_STRVAR(extend__doc__,
2273"B.extend(iterable int) -> None\n\
2274\n\
2275Append all the elements from the iterator or sequence to the\n\
2276end of B.");
2277static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002278bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002279{
Benjamin Petersond6720012009-04-18 15:31:34 +00002280 PyObject *it, *item, *bytearray_obj;
Christian Heimes44720832008-05-26 13:01:01 +00002281 Py_ssize_t buf_size = 0, len = 0;
2282 int value;
2283 char *buf;
2284
Benjamin Petersond6720012009-04-18 15:31:34 +00002285 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes44720832008-05-26 13:01:01 +00002286 if (PyObject_CheckBuffer(arg)) {
Benjamin Petersond6720012009-04-18 15:31:34 +00002287 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002288 return NULL;
2289
2290 Py_RETURN_NONE;
2291 }
2292
2293 it = PyObject_GetIter(arg);
2294 if (it == NULL)
2295 return NULL;
2296
Ezio Melotti24b07bc2011-03-15 18:55:01 +02002297 /* Try to determine the length of the argument. 32 is arbitrary. */
Christian Heimes44720832008-05-26 13:01:01 +00002298 buf_size = _PyObject_LengthHint(arg, 32);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002299 if (buf_size == -1) {
2300 Py_DECREF(it);
2301 return NULL;
2302 }
Christian Heimes44720832008-05-26 13:01:01 +00002303
Benjamin Petersond6720012009-04-18 15:31:34 +00002304 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitroufe941772012-04-01 16:05:46 +02002305 if (bytearray_obj == NULL) {
2306 Py_DECREF(it);
Christian Heimes44720832008-05-26 13:01:01 +00002307 return NULL;
Antoine Pitroufe941772012-04-01 16:05:46 +02002308 }
Benjamin Petersond6720012009-04-18 15:31:34 +00002309 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002310
2311 while ((item = PyIter_Next(it)) != NULL) {
2312 if (! _getbytevalue(item, &value)) {
2313 Py_DECREF(item);
2314 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002315 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002316 return NULL;
2317 }
2318 buf[len++] = value;
2319 Py_DECREF(item);
2320
2321 if (len >= buf_size) {
2322 buf_size = len + (len >> 1) + 1;
Benjamin Petersond6720012009-04-18 15:31:34 +00002323 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00002324 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002325 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002326 return NULL;
2327 }
2328 /* Recompute the `buf' pointer, since the resizing operation may
2329 have invalidated it. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002330 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002331 }
2332 }
2333 Py_DECREF(it);
2334
2335 /* Resize down to exact size. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002336 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2337 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002338 return NULL;
2339 }
2340
Antoine Pitroufe941772012-04-01 16:05:46 +02002341 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2342 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002343 return NULL;
Antoine Pitroufe941772012-04-01 16:05:46 +02002344 }
Benjamin Petersond6720012009-04-18 15:31:34 +00002345 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002346
2347 Py_RETURN_NONE;
2348}
2349
2350PyDoc_STRVAR(pop__doc__,
2351"B.pop([index]) -> int\n\
2352\n\
2353Remove and return a single item from B. If no index\n\
Andrew M. Kuchlingd8972642008-06-21 13:29:12 +00002354argument is given, will pop the last value.");
Christian Heimes44720832008-05-26 13:01:01 +00002355static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002356bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002357{
2358 int value;
2359 Py_ssize_t where = -1, n = Py_SIZE(self);
2360
2361 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2362 return NULL;
2363
2364 if (n == 0) {
Eli Bendersky680e6eb2011-03-04 06:14:56 +00002365 PyErr_SetString(PyExc_IndexError,
2366 "pop from empty bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002367 return NULL;
2368 }
2369 if (where < 0)
2370 where += Py_SIZE(self);
2371 if (where < 0 || where >= Py_SIZE(self)) {
2372 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2373 return NULL;
2374 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002375 if (!_canresize(self))
2376 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002377
2378 value = self->ob_bytes[where];
2379 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2380 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2381 return NULL;
2382
Mark Dickinsonc8a7c7c2009-09-06 10:03:31 +00002383 return PyInt_FromLong((unsigned char)value);
Christian Heimes44720832008-05-26 13:01:01 +00002384}
2385
2386PyDoc_STRVAR(remove__doc__,
2387"B.remove(int) -> None\n\
2388\n\
2389Remove the first occurance of a value in B.");
2390static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002391bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002392{
2393 int value;
2394 Py_ssize_t where, n = Py_SIZE(self);
2395
2396 if (! _getbytevalue(arg, &value))
2397 return NULL;
2398
2399 for (where = 0; where < n; where++) {
2400 if (self->ob_bytes[where] == value)
2401 break;
2402 }
2403 if (where == n) {
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002404 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002405 return NULL;
2406 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002407 if (!_canresize(self))
2408 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002409
2410 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2411 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2412 return NULL;
2413
2414 Py_RETURN_NONE;
2415}
2416
2417/* XXX These two helpers could be optimized if argsize == 1 */
2418
2419static Py_ssize_t
2420lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2421 void *argptr, Py_ssize_t argsize)
2422{
2423 Py_ssize_t i = 0;
2424 while (i < mysize && memchr(argptr, myptr[i], argsize))
2425 i++;
2426 return i;
2427}
2428
2429static Py_ssize_t
2430rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2431 void *argptr, Py_ssize_t argsize)
2432{
2433 Py_ssize_t i = mysize - 1;
2434 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2435 i--;
2436 return i + 1;
2437}
2438
2439PyDoc_STRVAR(strip__doc__,
2440"B.strip([bytes]) -> bytearray\n\
2441\n\
2442Strip leading and trailing bytes contained in the argument.\n\
2443If the argument is omitted, strip ASCII whitespace.");
2444static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002445bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002446{
2447 Py_ssize_t left, right, mysize, argsize;
2448 void *myptr, *argptr;
2449 PyObject *arg = Py_None;
2450 Py_buffer varg;
2451 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2452 return NULL;
2453 if (arg == Py_None) {
2454 argptr = "\t\n\r\f\v ";
2455 argsize = 6;
2456 }
2457 else {
2458 if (_getbuffer(arg, &varg) < 0)
2459 return NULL;
2460 argptr = varg.buf;
2461 argsize = varg.len;
2462 }
2463 myptr = self->ob_bytes;
2464 mysize = Py_SIZE(self);
2465 left = lstrip_helper(myptr, mysize, argptr, argsize);
2466 if (left == mysize)
2467 right = left;
2468 else
2469 right = rstrip_helper(myptr, mysize, argptr, argsize);
2470 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002471 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002472 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2473}
2474
2475PyDoc_STRVAR(lstrip__doc__,
2476"B.lstrip([bytes]) -> bytearray\n\
2477\n\
2478Strip leading bytes contained in the argument.\n\
2479If the argument is omitted, strip leading ASCII whitespace.");
2480static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002481bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002482{
2483 Py_ssize_t left, right, mysize, argsize;
2484 void *myptr, *argptr;
2485 PyObject *arg = Py_None;
2486 Py_buffer varg;
2487 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2488 return NULL;
2489 if (arg == Py_None) {
2490 argptr = "\t\n\r\f\v ";
2491 argsize = 6;
2492 }
2493 else {
2494 if (_getbuffer(arg, &varg) < 0)
2495 return NULL;
2496 argptr = varg.buf;
2497 argsize = varg.len;
2498 }
2499 myptr = self->ob_bytes;
2500 mysize = Py_SIZE(self);
2501 left = lstrip_helper(myptr, mysize, argptr, argsize);
2502 right = mysize;
2503 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002504 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002505 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2506}
2507
2508PyDoc_STRVAR(rstrip__doc__,
2509"B.rstrip([bytes]) -> bytearray\n\
2510\n\
2511Strip trailing bytes contained in the argument.\n\
2512If the argument is omitted, strip trailing ASCII whitespace.");
2513static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002514bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002515{
2516 Py_ssize_t left, right, mysize, argsize;
2517 void *myptr, *argptr;
2518 PyObject *arg = Py_None;
2519 Py_buffer varg;
2520 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2521 return NULL;
2522 if (arg == Py_None) {
2523 argptr = "\t\n\r\f\v ";
2524 argsize = 6;
2525 }
2526 else {
2527 if (_getbuffer(arg, &varg) < 0)
2528 return NULL;
2529 argptr = varg.buf;
2530 argsize = varg.len;
2531 }
2532 myptr = self->ob_bytes;
2533 mysize = Py_SIZE(self);
2534 left = 0;
2535 right = rstrip_helper(myptr, mysize, argptr, argsize);
2536 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002537 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002538 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2539}
2540
2541PyDoc_STRVAR(decode_doc,
2542"B.decode([encoding[, errors]]) -> unicode object.\n\
2543\n\
2544Decodes B using the codec registered for encoding. encoding defaults\n\
2545to the default encoding. errors may be given to set a different error\n\
2546handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2547a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2548as well as any other name registered with codecs.register_error that is\n\
2549able to handle UnicodeDecodeErrors.");
2550
2551static PyObject *
Benjamin Petersondc782b52009-09-18 21:46:21 +00002552bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes44720832008-05-26 13:01:01 +00002553{
2554 const char *encoding = NULL;
2555 const char *errors = NULL;
Benjamin Petersondc782b52009-09-18 21:46:21 +00002556 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes44720832008-05-26 13:01:01 +00002557
Benjamin Petersondc782b52009-09-18 21:46:21 +00002558 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes44720832008-05-26 13:01:01 +00002559 return NULL;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002560 if (encoding == NULL) {
2561#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002562 encoding = PyUnicode_GetDefaultEncoding();
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002563#else
2564 PyErr_SetString(PyExc_ValueError, "no encoding specified");
2565 return NULL;
2566#endif
2567 }
Christian Heimes44720832008-05-26 13:01:01 +00002568 return PyCodec_Decode(self, encoding, errors);
2569}
2570
2571PyDoc_STRVAR(alloc_doc,
2572"B.__alloc__() -> int\n\
2573\n\
2574Returns the number of bytes actually allocated.");
2575
2576static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002577bytearray_alloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002578{
2579 return PyInt_FromSsize_t(self->ob_alloc);
2580}
2581
2582PyDoc_STRVAR(join_doc,
2583"B.join(iterable_of_bytes) -> bytes\n\
2584\n\
2585Concatenates any number of bytearray objects, with B in between each pair.");
2586
2587static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002588bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002589{
2590 PyObject *seq;
2591 Py_ssize_t mysize = Py_SIZE(self);
2592 Py_ssize_t i;
2593 Py_ssize_t n;
2594 PyObject **items;
2595 Py_ssize_t totalsize = 0;
2596 PyObject *result;
2597 char *dest;
2598
2599 seq = PySequence_Fast(it, "can only join an iterable");
2600 if (seq == NULL)
2601 return NULL;
2602 n = PySequence_Fast_GET_SIZE(seq);
2603 items = PySequence_Fast_ITEMS(seq);
2604
2605 /* Compute the total size, and check that they are all bytes */
2606 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2607 for (i = 0; i < n; i++) {
2608 PyObject *obj = items[i];
2609 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2610 PyErr_Format(PyExc_TypeError,
2611 "can only join an iterable of bytes "
2612 "(item %ld has type '%.100s')",
2613 /* XXX %ld isn't right on Win64 */
2614 (long)i, Py_TYPE(obj)->tp_name);
2615 goto error;
2616 }
2617 if (i > 0)
2618 totalsize += mysize;
2619 totalsize += Py_SIZE(obj);
2620 if (totalsize < 0) {
2621 PyErr_NoMemory();
2622 goto error;
2623 }
2624 }
2625
2626 /* Allocate the result, and copy the bytes */
2627 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2628 if (result == NULL)
2629 goto error;
2630 dest = PyByteArray_AS_STRING(result);
2631 for (i = 0; i < n; i++) {
2632 PyObject *obj = items[i];
2633 Py_ssize_t size = Py_SIZE(obj);
2634 char *buf;
2635 if (PyByteArray_Check(obj))
2636 buf = PyByteArray_AS_STRING(obj);
2637 else
2638 buf = PyBytes_AS_STRING(obj);
2639 if (i) {
2640 memcpy(dest, self->ob_bytes, mysize);
2641 dest += mysize;
2642 }
2643 memcpy(dest, buf, size);
2644 dest += size;
2645 }
2646
2647 /* Done */
2648 Py_DECREF(seq);
2649 return result;
2650
2651 /* Error handling */
2652 error:
2653 Py_DECREF(seq);
2654 return NULL;
2655}
2656
Antoine Pitrou64672132010-01-13 07:55:48 +00002657PyDoc_STRVAR(splitlines__doc__,
Raymond Hettingeraad5b022012-06-02 01:42:58 -04002658"B.splitlines(keepends=False) -> list of lines\n\
Antoine Pitrou64672132010-01-13 07:55:48 +00002659\n\
2660Return a list of the lines in B, breaking at line boundaries.\n\
2661Line breaks are not included in the resulting list unless keepends\n\
2662is given and true.");
2663
2664static PyObject*
2665bytearray_splitlines(PyObject *self, PyObject *args)
2666{
2667 int keepends = 0;
2668
2669 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2670 return NULL;
2671
2672 return stringlib_splitlines(
2673 (PyObject*) self, PyByteArray_AS_STRING(self),
2674 PyByteArray_GET_SIZE(self), keepends
2675 );
2676}
2677
Christian Heimes44720832008-05-26 13:01:01 +00002678PyDoc_STRVAR(fromhex_doc,
2679"bytearray.fromhex(string) -> bytearray\n\
2680\n\
2681Create a bytearray object from a string of hexadecimal numbers.\n\
2682Spaces between two numbers are accepted.\n\
2683Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2684
2685static int
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002686hex_digit_to_int(char c)
Christian Heimes44720832008-05-26 13:01:01 +00002687{
Eric Smithcac7af62009-04-27 19:04:37 +00002688 if (Py_ISDIGIT(c))
Christian Heimes44720832008-05-26 13:01:01 +00002689 return c - '0';
2690 else {
Eric Smithcac7af62009-04-27 19:04:37 +00002691 if (Py_ISUPPER(c))
2692 c = Py_TOLOWER(c);
Christian Heimes44720832008-05-26 13:01:01 +00002693 if (c >= 'a' && c <= 'f')
2694 return c - 'a' + 10;
2695 }
2696 return -1;
2697}
2698
2699static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002700bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002701{
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002702 PyObject *newbytes;
Christian Heimes44720832008-05-26 13:01:01 +00002703 char *buf;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002704 char *hex;
Christian Heimes44720832008-05-26 13:01:01 +00002705 Py_ssize_t hexlen, byteslen, i, j;
2706 int top, bot;
2707
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002708 if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
Christian Heimes44720832008-05-26 13:01:01 +00002709 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002710 byteslen = hexlen/2; /* This overestimates if there are spaces */
2711 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2712 if (!newbytes)
2713 return NULL;
2714 buf = PyByteArray_AS_STRING(newbytes);
2715 for (i = j = 0; i < hexlen; i += 2) {
2716 /* skip over spaces in the input */
2717 while (hex[i] == ' ')
2718 i++;
2719 if (i >= hexlen)
2720 break;
2721 top = hex_digit_to_int(hex[i]);
2722 bot = hex_digit_to_int(hex[i+1]);
2723 if (top == -1 || bot == -1) {
2724 PyErr_Format(PyExc_ValueError,
2725 "non-hexadecimal number found in "
2726 "fromhex() arg at position %zd", i);
2727 goto error;
2728 }
2729 buf[j++] = (top << 4) + bot;
2730 }
2731 if (PyByteArray_Resize(newbytes, j) < 0)
2732 goto error;
2733 return newbytes;
2734
2735 error:
2736 Py_DECREF(newbytes);
2737 return NULL;
2738}
2739
2740PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2741
2742static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002743bytearray_reduce(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002744{
2745 PyObject *latin1, *dict;
2746 if (self->ob_bytes)
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002747#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002748 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2749 Py_SIZE(self), NULL);
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002750#else
Mark Dickinson9d109742009-10-15 15:18:55 +00002751 latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002752#endif
Christian Heimes44720832008-05-26 13:01:01 +00002753 else
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002754#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002755 latin1 = PyUnicode_FromString("");
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002756#else
2757 latin1 = PyString_FromString("");
2758#endif
Christian Heimes44720832008-05-26 13:01:01 +00002759
2760 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2761 if (dict == NULL) {
2762 PyErr_Clear();
2763 dict = Py_None;
2764 Py_INCREF(dict);
2765 }
2766
2767 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2768}
2769
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002770PyDoc_STRVAR(sizeof_doc,
2771"B.__sizeof__() -> int\n\
2772 \n\
2773Returns the size of B in memory, in bytes");
2774static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002775bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002776{
Georg Brandl517cfdc2009-04-05 13:16:35 +00002777 Py_ssize_t res;
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002778
Georg Brandl517cfdc2009-04-05 13:16:35 +00002779 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2780 return PyInt_FromSsize_t(res);
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002781}
2782
Benjamin Petersond6720012009-04-18 15:31:34 +00002783static PySequenceMethods bytearray_as_sequence = {
2784 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes44720832008-05-26 13:01:01 +00002785 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Petersond6720012009-04-18 15:31:34 +00002786 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2787 (ssizeargfunc)bytearray_getitem, /* sq_item */
2788 0, /* sq_slice */
2789 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2790 0, /* sq_ass_slice */
2791 (objobjproc)bytearray_contains, /* sq_contains */
2792 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2793 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes44720832008-05-26 13:01:01 +00002794};
2795
Benjamin Petersond6720012009-04-18 15:31:34 +00002796static PyMappingMethods bytearray_as_mapping = {
2797 (lenfunc)bytearray_length,
2798 (binaryfunc)bytearray_subscript,
2799 (objobjargproc)bytearray_ass_subscript,
Christian Heimes44720832008-05-26 13:01:01 +00002800};
2801
Benjamin Petersond6720012009-04-18 15:31:34 +00002802static PyBufferProcs bytearray_as_buffer = {
2803 (readbufferproc)bytearray_buffer_getreadbuf,
2804 (writebufferproc)bytearray_buffer_getwritebuf,
2805 (segcountproc)bytearray_buffer_getsegcount,
2806 (charbufferproc)bytearray_buffer_getcharbuf,
2807 (getbufferproc)bytearray_getbuffer,
2808 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes44720832008-05-26 13:01:01 +00002809};
2810
2811static PyMethodDef
Benjamin Petersond6720012009-04-18 15:31:34 +00002812bytearray_methods[] = {
2813 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2814 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2815 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2816 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002817 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2818 _Py_capitalize__doc__},
2819 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002820 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Petersondc782b52009-09-18 21:46:21 +00002821 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002822 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002823 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2824 expandtabs__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002825 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2826 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2827 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes44720832008-05-26 13:01:01 +00002828 fromhex_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002829 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2830 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002831 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2832 _Py_isalnum__doc__},
2833 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2834 _Py_isalpha__doc__},
2835 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2836 _Py_isdigit__doc__},
2837 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2838 _Py_islower__doc__},
2839 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2840 _Py_isspace__doc__},
2841 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2842 _Py_istitle__doc__},
2843 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2844 _Py_isupper__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002845 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes44720832008-05-26 13:01:01 +00002846 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2847 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002848 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2849 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2850 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2851 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2852 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2853 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2854 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2855 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002856 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002857 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2858 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2859 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2860 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrou64672132010-01-13 07:55:48 +00002861 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002862 splitlines__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002863 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes44720832008-05-26 13:01:01 +00002864 startswith__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002865 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002866 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2867 _Py_swapcase__doc__},
2868 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002869 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002870 translate__doc__},
2871 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2872 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2873 {NULL}
2874};
2875
Benjamin Petersond6720012009-04-18 15:31:34 +00002876PyDoc_STRVAR(bytearray_doc,
Christian Heimes44720832008-05-26 13:01:01 +00002877"bytearray(iterable_of_ints) -> bytearray.\n\
2878bytearray(string, encoding[, errors]) -> bytearray.\n\
2879bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
2880bytearray(memory_view) -> bytearray.\n\
2881\n\
2882Construct an mutable bytearray object from:\n\
2883 - an iterable yielding integers in range(256)\n\
2884 - a text string encoded using the specified encoding\n\
2885 - a bytes or a bytearray object\n\
2886 - any object implementing the buffer API.\n\
2887\n\
2888bytearray(int) -> bytearray.\n\
2889\n\
2890Construct a zero-initialized bytearray of the given length.");
2891
2892
Benjamin Petersond6720012009-04-18 15:31:34 +00002893static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes44720832008-05-26 13:01:01 +00002894
2895PyTypeObject PyByteArray_Type = {
2896 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2897 "bytearray",
2898 sizeof(PyByteArrayObject),
2899 0,
Benjamin Petersond6720012009-04-18 15:31:34 +00002900 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00002901 0, /* tp_print */
2902 0, /* tp_getattr */
2903 0, /* tp_setattr */
2904 0, /* tp_compare */
Benjamin Petersond6720012009-04-18 15:31:34 +00002905 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes44720832008-05-26 13:01:01 +00002906 0, /* tp_as_number */
Benjamin Petersond6720012009-04-18 15:31:34 +00002907 &bytearray_as_sequence, /* tp_as_sequence */
2908 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes44720832008-05-26 13:01:01 +00002909 0, /* tp_hash */
2910 0, /* tp_call */
Benjamin Petersond6720012009-04-18 15:31:34 +00002911 bytearray_str, /* tp_str */
Christian Heimes44720832008-05-26 13:01:01 +00002912 PyObject_GenericGetAttr, /* tp_getattro */
2913 0, /* tp_setattro */
Benjamin Petersond6720012009-04-18 15:31:34 +00002914 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes44720832008-05-26 13:01:01 +00002915 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2916 Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
Benjamin Petersond6720012009-04-18 15:31:34 +00002917 bytearray_doc, /* tp_doc */
Christian Heimes44720832008-05-26 13:01:01 +00002918 0, /* tp_traverse */
2919 0, /* tp_clear */
Benjamin Petersond6720012009-04-18 15:31:34 +00002920 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes44720832008-05-26 13:01:01 +00002921 0, /* tp_weaklistoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002922 bytearray_iter, /* tp_iter */
Christian Heimes44720832008-05-26 13:01:01 +00002923 0, /* tp_iternext */
Benjamin Petersond6720012009-04-18 15:31:34 +00002924 bytearray_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00002925 0, /* tp_members */
2926 0, /* tp_getset */
2927 0, /* tp_base */
2928 0, /* tp_dict */
2929 0, /* tp_descr_get */
2930 0, /* tp_descr_set */
2931 0, /* tp_dictoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002932 (initproc)bytearray_init, /* tp_init */
Christian Heimes44720832008-05-26 13:01:01 +00002933 PyType_GenericAlloc, /* tp_alloc */
2934 PyType_GenericNew, /* tp_new */
2935 PyObject_Del, /* tp_free */
2936};
2937
2938/*********************** Bytes Iterator ****************************/
2939
2940typedef struct {
2941 PyObject_HEAD
2942 Py_ssize_t it_index;
2943 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2944} bytesiterobject;
2945
2946static void
Benjamin Petersond6720012009-04-18 15:31:34 +00002947bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002948{
2949 _PyObject_GC_UNTRACK(it);
2950 Py_XDECREF(it->it_seq);
2951 PyObject_GC_Del(it);
2952}
2953
2954static int
Benjamin Petersond6720012009-04-18 15:31:34 +00002955bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002956{
2957 Py_VISIT(it->it_seq);
2958 return 0;
2959}
2960
2961static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002962bytearrayiter_next(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002963{
2964 PyByteArrayObject *seq;
2965 PyObject *item;
2966
2967 assert(it != NULL);
2968 seq = it->it_seq;
2969 if (seq == NULL)
2970 return NULL;
2971 assert(PyByteArray_Check(seq));
2972
2973 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2974 item = PyInt_FromLong(
2975 (unsigned char)seq->ob_bytes[it->it_index]);
2976 if (item != NULL)
2977 ++it->it_index;
2978 return item;
2979 }
2980
2981 Py_DECREF(seq);
2982 it->it_seq = NULL;
2983 return NULL;
2984}
2985
2986static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002987bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002988{
2989 Py_ssize_t len = 0;
2990 if (it->it_seq)
2991 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2992 return PyInt_FromSsize_t(len);
2993}
2994
2995PyDoc_STRVAR(length_hint_doc,
2996 "Private method returning an estimate of len(list(it)).");
2997
Benjamin Petersond6720012009-04-18 15:31:34 +00002998static PyMethodDef bytearrayiter_methods[] = {
2999 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes44720832008-05-26 13:01:01 +00003000 length_hint_doc},
3001 {NULL, NULL} /* sentinel */
3002};
3003
3004PyTypeObject PyByteArrayIter_Type = {
3005 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3006 "bytearray_iterator", /* tp_name */
3007 sizeof(bytesiterobject), /* tp_basicsize */
3008 0, /* tp_itemsize */
3009 /* methods */
Benjamin Petersond6720012009-04-18 15:31:34 +00003010 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00003011 0, /* tp_print */
3012 0, /* tp_getattr */
3013 0, /* tp_setattr */
3014 0, /* tp_compare */
3015 0, /* tp_repr */
3016 0, /* tp_as_number */
3017 0, /* tp_as_sequence */
3018 0, /* tp_as_mapping */
3019 0, /* tp_hash */
3020 0, /* tp_call */
3021 0, /* tp_str */
3022 PyObject_GenericGetAttr, /* tp_getattro */
3023 0, /* tp_setattro */
3024 0, /* tp_as_buffer */
3025 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3026 0, /* tp_doc */
Benjamin Petersond6720012009-04-18 15:31:34 +00003027 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes44720832008-05-26 13:01:01 +00003028 0, /* tp_clear */
3029 0, /* tp_richcompare */
3030 0, /* tp_weaklistoffset */
3031 PyObject_SelfIter, /* tp_iter */
Benjamin Petersond6720012009-04-18 15:31:34 +00003032 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3033 bytearrayiter_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00003034 0,
3035};
3036
3037static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003038bytearray_iter(PyObject *seq)
Christian Heimes44720832008-05-26 13:01:01 +00003039{
3040 bytesiterobject *it;
3041
3042 if (!PyByteArray_Check(seq)) {
3043 PyErr_BadInternalCall();
3044 return NULL;
3045 }
3046 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3047 if (it == NULL)
3048 return NULL;
3049 it->it_index = 0;
3050 Py_INCREF(seq);
3051 it->it_seq = (PyByteArrayObject *)seq;
3052 _PyObject_GC_TRACK(it);
3053 return (PyObject *)it;
3054}