blob: a40c0ab7ff74f6bc25ab56ed79b7db65bca4d71d [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)) {
Georg Brandl28dadd92011-02-25 10:50:32 +0000639 /* Make a copy and call this function recursively */
Christian Heimes44720832008-05-26 13:01:01 +0000640 int err;
641 values = PyByteArray_FromObject(values);
642 if (values == NULL)
643 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000644 err = bytearray_ass_subscript(self, index, values);
Christian Heimes44720832008-05-26 13:01:01 +0000645 Py_DECREF(values);
646 return err;
647 }
648 else {
649 assert(PyByteArray_Check(values));
650 bytes = ((PyByteArrayObject *)values)->ob_bytes;
651 needed = Py_SIZE(values);
652 }
653 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
654 if ((step < 0 && start < stop) ||
655 (step > 0 && start > stop))
656 stop = start;
657 if (step == 1) {
658 if (slicelen != needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000659 if (!_canresize(self))
660 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000661 if (slicelen > needed) {
662 /*
663 0 start stop old_size
664 | |<---slicelen--->|<-----tomove------>|
665 | |<-needed->|<-----tomove------>|
666 0 lo new_hi new_size
667 */
668 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
669 Py_SIZE(self) - stop);
670 }
671 if (PyByteArray_Resize((PyObject *)self,
672 Py_SIZE(self) + needed - slicelen) < 0)
673 return -1;
674 if (slicelen < needed) {
675 /*
676 0 lo hi old_size
677 | |<-avail->|<-----tomove------>|
678 | |<----needed---->|<-----tomove------>|
679 0 lo new_hi new_size
680 */
681 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
682 Py_SIZE(self) - start - needed);
683 }
684 }
685
686 if (needed > 0)
687 memcpy(self->ob_bytes + start, bytes, needed);
688
689 return 0;
690 }
691 else {
692 if (needed == 0) {
693 /* Delete slice */
Mark Dickinson36ecd672010-01-29 17:11:39 +0000694 size_t cur;
695 Py_ssize_t i;
Christian Heimes44720832008-05-26 13:01:01 +0000696
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000697 if (!_canresize(self))
698 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000699 if (step < 0) {
700 stop = start + 1;
701 start = stop + step * (slicelen - 1) - 1;
702 step = -step;
703 }
704 for (cur = start, i = 0;
705 i < slicelen; cur += step, i++) {
706 Py_ssize_t lim = step - 1;
707
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000708 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes44720832008-05-26 13:01:01 +0000709 lim = PyByteArray_GET_SIZE(self) - cur - 1;
710
711 memmove(self->ob_bytes + cur - i,
712 self->ob_bytes + cur + 1, lim);
713 }
714 /* Move the tail of the bytes, in one chunk */
715 cur = start + slicelen*step;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000716 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Christian Heimes44720832008-05-26 13:01:01 +0000717 memmove(self->ob_bytes + cur - slicelen,
718 self->ob_bytes + cur,
719 PyByteArray_GET_SIZE(self) - cur);
720 }
721 if (PyByteArray_Resize((PyObject *)self,
722 PyByteArray_GET_SIZE(self) - slicelen) < 0)
723 return -1;
724
725 return 0;
726 }
727 else {
728 /* Assign slice */
729 Py_ssize_t cur, i;
730
731 if (needed != slicelen) {
732 PyErr_Format(PyExc_ValueError,
733 "attempt to assign bytes of size %zd "
734 "to extended slice of size %zd",
735 needed, slicelen);
736 return -1;
737 }
738 for (cur = start, i = 0; i < slicelen; cur += step, i++)
739 self->ob_bytes[cur] = bytes[i];
740 return 0;
741 }
742 }
743}
744
745static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000746bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes44720832008-05-26 13:01:01 +0000747{
748 static char *kwlist[] = {"source", "encoding", "errors", 0};
749 PyObject *arg = NULL;
750 const char *encoding = NULL;
751 const char *errors = NULL;
752 Py_ssize_t count;
753 PyObject *it;
754 PyObject *(*iternext)(PyObject *);
755
756 if (Py_SIZE(self) != 0) {
757 /* Empty previous contents (yes, do this first of all!) */
758 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
759 return -1;
760 }
761
762 /* Parse arguments */
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000763 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes44720832008-05-26 13:01:01 +0000764 &arg, &encoding, &errors))
765 return -1;
766
767 /* Make a quick exit if no first argument */
768 if (arg == NULL) {
769 if (encoding != NULL || errors != NULL) {
770 PyErr_SetString(PyExc_TypeError,
771 "encoding or errors without sequence argument");
772 return -1;
773 }
774 return 0;
775 }
776
777 if (PyBytes_Check(arg)) {
778 PyObject *new, *encoded;
779 if (encoding != NULL) {
780 encoded = PyCodec_Encode(arg, encoding, errors);
781 if (encoded == NULL)
782 return -1;
783 assert(PyBytes_Check(encoded));
784 }
785 else {
786 encoded = arg;
787 Py_INCREF(arg);
788 }
Benjamin Petersond6720012009-04-18 15:31:34 +0000789 new = bytearray_iconcat(self, arg);
Christian Heimes44720832008-05-26 13:01:01 +0000790 Py_DECREF(encoded);
791 if (new == NULL)
792 return -1;
793 Py_DECREF(new);
794 return 0;
795 }
796
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000797#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +0000798 if (PyUnicode_Check(arg)) {
799 /* Encode via the codec registry */
800 PyObject *encoded, *new;
801 if (encoding == NULL) {
802 PyErr_SetString(PyExc_TypeError,
803 "unicode argument without an encoding");
804 return -1;
805 }
806 encoded = PyCodec_Encode(arg, encoding, errors);
807 if (encoded == NULL)
808 return -1;
809 assert(PyBytes_Check(encoded));
Benjamin Petersond6720012009-04-18 15:31:34 +0000810 new = bytearray_iconcat(self, encoded);
Christian Heimes44720832008-05-26 13:01:01 +0000811 Py_DECREF(encoded);
812 if (new == NULL)
813 return -1;
814 Py_DECREF(new);
815 return 0;
816 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000817#endif
Christian Heimes44720832008-05-26 13:01:01 +0000818
819 /* If it's not unicode, there can't be encoding or errors */
820 if (encoding != NULL || errors != NULL) {
821 PyErr_SetString(PyExc_TypeError,
822 "encoding or errors without a string argument");
823 return -1;
824 }
825
826 /* Is it an int? */
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000827 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
828 if (count == -1 && PyErr_Occurred()) {
829 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes44720832008-05-26 13:01:01 +0000830 return -1;
Benjamin Petersonae530c22010-04-16 22:52:44 +0000831 PyErr_Clear();
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000832 }
833 else if (count < 0) {
834 PyErr_SetString(PyExc_ValueError, "negative count");
835 return -1;
836 }
837 else {
Christian Heimes44720832008-05-26 13:01:01 +0000838 if (count > 0) {
839 if (PyByteArray_Resize((PyObject *)self, count))
840 return -1;
841 memset(self->ob_bytes, 0, count);
842 }
843 return 0;
844 }
845
846 /* Use the buffer API */
847 if (PyObject_CheckBuffer(arg)) {
848 Py_ssize_t size;
849 Py_buffer view;
850 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
851 return -1;
852 size = view.len;
853 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
854 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
855 goto fail;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000856 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000857 return 0;
858 fail:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000859 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000860 return -1;
861 }
862
863 /* XXX Optimize this if the arguments is a list, tuple */
864
865 /* Get the iterator */
866 it = PyObject_GetIter(arg);
867 if (it == NULL)
868 return -1;
869 iternext = *Py_TYPE(it)->tp_iternext;
870
871 /* Run the iterator to exhaustion */
872 for (;;) {
873 PyObject *item;
Georg Brandl3e758462008-07-16 23:10:05 +0000874 int rc, value;
Christian Heimes44720832008-05-26 13:01:01 +0000875
876 /* Get the next item */
877 item = iternext(it);
878 if (item == NULL) {
879 if (PyErr_Occurred()) {
880 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
881 goto error;
882 PyErr_Clear();
883 }
884 break;
885 }
886
887 /* Interpret it as an int (__index__) */
Georg Brandl3e758462008-07-16 23:10:05 +0000888 rc = _getbytevalue(item, &value);
Christian Heimes44720832008-05-26 13:01:01 +0000889 Py_DECREF(item);
Georg Brandl3e758462008-07-16 23:10:05 +0000890 if (!rc)
Christian Heimes44720832008-05-26 13:01:01 +0000891 goto error;
892
Christian Heimes44720832008-05-26 13:01:01 +0000893 /* Append the byte */
894 if (Py_SIZE(self) < self->ob_alloc)
895 Py_SIZE(self)++;
896 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
897 goto error;
898 self->ob_bytes[Py_SIZE(self)-1] = value;
899 }
900
901 /* Clean up and return success */
902 Py_DECREF(it);
903 return 0;
904
905 error:
906 /* Error handling when it != NULL */
907 Py_DECREF(it);
908 return -1;
909}
910
911/* Mostly copied from string_repr, but without the
912 "smart quote" functionality. */
913static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000914bytearray_repr(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000915{
916 static const char *hexdigits = "0123456789abcdef";
917 const char *quote_prefix = "bytearray(b";
918 const char *quote_postfix = ")";
919 Py_ssize_t length = Py_SIZE(self);
920 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000921 size_t newsize;
Christian Heimes44720832008-05-26 13:01:01 +0000922 PyObject *v;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000923 if (length > (PY_SSIZE_T_MAX - 14) / 4) {
Christian Heimes44720832008-05-26 13:01:01 +0000924 PyErr_SetString(PyExc_OverflowError,
925 "bytearray object is too large to make repr");
926 return NULL;
927 }
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000928 newsize = 14 + 4 * length;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000929 v = PyString_FromStringAndSize(NULL, newsize);
Christian Heimes44720832008-05-26 13:01:01 +0000930 if (v == NULL) {
931 return NULL;
932 }
933 else {
934 register Py_ssize_t i;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000935 register char c;
936 register char *p;
Christian Heimes44720832008-05-26 13:01:01 +0000937 int quote;
938
939 /* Figure out which quote to use; single is preferred */
940 quote = '\'';
941 {
942 char *test, *start;
943 start = PyByteArray_AS_STRING(self);
944 for (test = start; test < start+length; ++test) {
945 if (*test == '"') {
946 quote = '\''; /* back to single */
947 goto decided;
948 }
949 else if (*test == '\'')
950 quote = '"';
951 }
952 decided:
953 ;
954 }
955
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000956 p = PyString_AS_STRING(v);
Christian Heimes44720832008-05-26 13:01:01 +0000957 while (*quote_prefix)
958 *p++ = *quote_prefix++;
959 *p++ = quote;
960
961 for (i = 0; i < length; i++) {
962 /* There's at least enough room for a hex escape
963 and a closing quote. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000964 assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
Christian Heimes44720832008-05-26 13:01:01 +0000965 c = self->ob_bytes[i];
966 if (c == '\'' || c == '\\')
967 *p++ = '\\', *p++ = c;
968 else if (c == '\t')
969 *p++ = '\\', *p++ = 't';
970 else if (c == '\n')
971 *p++ = '\\', *p++ = 'n';
972 else if (c == '\r')
973 *p++ = '\\', *p++ = 'r';
974 else if (c == 0)
975 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
976 else if (c < ' ' || c >= 0x7f) {
977 *p++ = '\\';
978 *p++ = 'x';
979 *p++ = hexdigits[(c & 0xf0) >> 4];
980 *p++ = hexdigits[c & 0xf];
981 }
982 else
983 *p++ = c;
984 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000985 assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
Christian Heimes44720832008-05-26 13:01:01 +0000986 *p++ = quote;
987 while (*quote_postfix) {
988 *p++ = *quote_postfix++;
989 }
990 *p = '\0';
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000991 if (_PyString_Resize(&v, (p - PyString_AS_STRING(v)))) {
Christian Heimes44720832008-05-26 13:01:01 +0000992 Py_DECREF(v);
993 return NULL;
994 }
995 return v;
996 }
997}
998
999static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001000bytearray_str(PyObject *op)
Christian Heimes44720832008-05-26 13:01:01 +00001001{
1002#if 0
1003 if (Py_BytesWarningFlag) {
1004 if (PyErr_WarnEx(PyExc_BytesWarning,
1005 "str() on a bytearray instance", 1))
1006 return NULL;
1007 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001008 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes44720832008-05-26 13:01:01 +00001009#endif
1010 return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
1011}
1012
1013static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001014bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes44720832008-05-26 13:01:01 +00001015{
1016 Py_ssize_t self_size, other_size;
1017 Py_buffer self_bytes, other_bytes;
1018 PyObject *res;
1019 Py_ssize_t minsize;
1020 int cmp;
1021
1022 /* Bytes can be compared to anything that supports the (binary)
1023 buffer API. Except that a comparison with Unicode is always an
1024 error, even if the comparison is for equality. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001025#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00001026 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1027 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
1028 if (Py_BytesWarningFlag && op == Py_EQ) {
1029 if (PyErr_WarnEx(PyExc_BytesWarning,
Ezio Melottid2342082010-01-14 11:34:10 +00001030 "Comparison between bytearray and string", 1))
Christian Heimes44720832008-05-26 13:01:01 +00001031 return NULL;
1032 }
1033
1034 Py_INCREF(Py_NotImplemented);
1035 return Py_NotImplemented;
1036 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001037#endif
Christian Heimes44720832008-05-26 13:01:01 +00001038
1039 self_size = _getbuffer(self, &self_bytes);
1040 if (self_size < 0) {
1041 PyErr_Clear();
1042 Py_INCREF(Py_NotImplemented);
1043 return Py_NotImplemented;
1044 }
1045
1046 other_size = _getbuffer(other, &other_bytes);
1047 if (other_size < 0) {
1048 PyErr_Clear();
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001049 PyBuffer_Release(&self_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001050 Py_INCREF(Py_NotImplemented);
1051 return Py_NotImplemented;
1052 }
1053
1054 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1055 /* Shortcut: if the lengths differ, the objects differ */
1056 cmp = (op == Py_NE);
1057 }
1058 else {
1059 minsize = self_size;
1060 if (other_size < minsize)
1061 minsize = other_size;
1062
1063 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1064 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1065
1066 if (cmp == 0) {
1067 if (self_size < other_size)
1068 cmp = -1;
1069 else if (self_size > other_size)
1070 cmp = 1;
1071 }
1072
1073 switch (op) {
1074 case Py_LT: cmp = cmp < 0; break;
1075 case Py_LE: cmp = cmp <= 0; break;
1076 case Py_EQ: cmp = cmp == 0; break;
1077 case Py_NE: cmp = cmp != 0; break;
1078 case Py_GT: cmp = cmp > 0; break;
1079 case Py_GE: cmp = cmp >= 0; break;
1080 }
1081 }
1082
1083 res = cmp ? Py_True : Py_False;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001084 PyBuffer_Release(&self_bytes);
1085 PyBuffer_Release(&other_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001086 Py_INCREF(res);
1087 return res;
1088}
1089
1090static void
Benjamin Petersond6720012009-04-18 15:31:34 +00001091bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00001092{
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001093 if (self->ob_exports > 0) {
1094 PyErr_SetString(PyExc_SystemError,
Georg Brandl517cfdc2009-04-05 13:16:35 +00001095 "deallocated bytearray object has exported buffers");
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001096 PyErr_Print();
1097 }
Christian Heimes44720832008-05-26 13:01:01 +00001098 if (self->ob_bytes != 0) {
1099 PyMem_Free(self->ob_bytes);
1100 }
1101 Py_TYPE(self)->tp_free((PyObject *)self);
1102}
1103
1104
1105/* -------------------------------------------------------------------- */
1106/* Methods */
1107
1108#define STRINGLIB_CHAR char
Christian Heimes44720832008-05-26 13:01:01 +00001109#define STRINGLIB_LEN PyByteArray_GET_SIZE
1110#define STRINGLIB_STR PyByteArray_AS_STRING
1111#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrou64672132010-01-13 07:55:48 +00001112#define STRINGLIB_ISSPACE Py_ISSPACE
1113#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes44720832008-05-26 13:01:01 +00001114#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1115#define STRINGLIB_MUTABLE 1
1116
1117#include "stringlib/fastsearch.h"
1118#include "stringlib/count.h"
1119#include "stringlib/find.h"
1120#include "stringlib/partition.h"
Antoine Pitrou64672132010-01-13 07:55:48 +00001121#include "stringlib/split.h"
Christian Heimes44720832008-05-26 13:01:01 +00001122#include "stringlib/ctype.h"
1123#include "stringlib/transmogrify.h"
1124
1125
1126/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1127were copied from the old char* style string object. */
1128
Antoine Pitrou64672132010-01-13 07:55:48 +00001129/* helper macro to fixup start/end slice values */
1130#define ADJUST_INDICES(start, end, len) \
1131 if (end > len) \
1132 end = len; \
1133 else if (end < 0) { \
1134 end += len; \
1135 if (end < 0) \
1136 end = 0; \
1137 } \
1138 if (start < 0) { \
1139 start += len; \
1140 if (start < 0) \
1141 start = 0; \
1142 }
Christian Heimes44720832008-05-26 13:01:01 +00001143
1144Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Petersond6720012009-04-18 15:31:34 +00001145bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes44720832008-05-26 13:01:01 +00001146{
1147 PyObject *subobj;
1148 Py_buffer subbuf;
1149 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1150 Py_ssize_t res;
1151
Jesus Cea44e81682011-04-20 16:39:15 +02001152 if (!stringlib_parse_args_finds("find/rfind/index/rindex",
1153 args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001154 return -2;
1155 if (_getbuffer(subobj, &subbuf) < 0)
1156 return -2;
1157 if (dir > 0)
1158 res = stringlib_find_slice(
1159 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1160 subbuf.buf, subbuf.len, start, end);
1161 else
1162 res = stringlib_rfind_slice(
1163 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1164 subbuf.buf, subbuf.len, start, end);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001165 PyBuffer_Release(&subbuf);
Christian Heimes44720832008-05-26 13:01:01 +00001166 return res;
1167}
1168
1169PyDoc_STRVAR(find__doc__,
1170"B.find(sub [,start [,end]]) -> int\n\
1171\n\
1172Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran5e3a19d2011-07-27 23:36:51 +08001173such that sub is contained within B[start,end]. Optional\n\
Christian Heimes44720832008-05-26 13:01:01 +00001174arguments start and end are interpreted as in slice notation.\n\
1175\n\
1176Return -1 on failure.");
1177
1178static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001179bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001180{
Benjamin Petersond6720012009-04-18 15:31:34 +00001181 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001182 if (result == -2)
1183 return NULL;
1184 return PyInt_FromSsize_t(result);
1185}
1186
1187PyDoc_STRVAR(count__doc__,
1188"B.count(sub [,start [,end]]) -> int\n\
1189\n\
1190Return the number of non-overlapping occurrences of subsection sub in\n\
1191bytes B[start:end]. Optional arguments start and end are interpreted\n\
1192as in slice notation.");
1193
1194static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001195bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001196{
1197 PyObject *sub_obj;
1198 const char *str = PyByteArray_AS_STRING(self);
1199 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1200 Py_buffer vsub;
1201 PyObject *count_obj;
1202
Jesus Cea44e81682011-04-20 16:39:15 +02001203 if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001204 return NULL;
1205
1206 if (_getbuffer(sub_obj, &vsub) < 0)
1207 return NULL;
1208
Antoine Pitrou64672132010-01-13 07:55:48 +00001209 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes44720832008-05-26 13:01:01 +00001210
1211 count_obj = PyInt_FromSsize_t(
Antoine Pitrou64672132010-01-13 07:55:48 +00001212 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes44720832008-05-26 13:01:01 +00001213 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001214 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00001215 return count_obj;
1216}
1217
1218
1219PyDoc_STRVAR(index__doc__,
1220"B.index(sub [,start [,end]]) -> int\n\
1221\n\
1222Like B.find() but raise ValueError when the subsection is not found.");
1223
1224static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001225bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001226{
Benjamin Petersond6720012009-04-18 15:31:34 +00001227 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001228 if (result == -2)
1229 return NULL;
1230 if (result == -1) {
1231 PyErr_SetString(PyExc_ValueError,
1232 "subsection not found");
1233 return NULL;
1234 }
1235 return PyInt_FromSsize_t(result);
1236}
1237
1238
1239PyDoc_STRVAR(rfind__doc__,
1240"B.rfind(sub [,start [,end]]) -> int\n\
1241\n\
1242Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran5e3a19d2011-07-27 23:36:51 +08001243such that sub is contained within B[start,end]. Optional\n\
Christian Heimes44720832008-05-26 13:01:01 +00001244arguments start and end are interpreted as in slice notation.\n\
1245\n\
1246Return -1 on failure.");
1247
1248static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001249bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001250{
Benjamin Petersond6720012009-04-18 15:31:34 +00001251 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001252 if (result == -2)
1253 return NULL;
1254 return PyInt_FromSsize_t(result);
1255}
1256
1257
1258PyDoc_STRVAR(rindex__doc__,
1259"B.rindex(sub [,start [,end]]) -> int\n\
1260\n\
1261Like B.rfind() but raise ValueError when the subsection is not found.");
1262
1263static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001264bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001265{
Benjamin Petersond6720012009-04-18 15:31:34 +00001266 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001267 if (result == -2)
1268 return NULL;
1269 if (result == -1) {
1270 PyErr_SetString(PyExc_ValueError,
1271 "subsection not found");
1272 return NULL;
1273 }
1274 return PyInt_FromSsize_t(result);
1275}
1276
1277
1278static int
Benjamin Petersond6720012009-04-18 15:31:34 +00001279bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00001280{
1281 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1282 if (ival == -1 && PyErr_Occurred()) {
1283 Py_buffer varg;
1284 int pos;
1285 PyErr_Clear();
1286 if (_getbuffer(arg, &varg) < 0)
1287 return -1;
1288 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1289 varg.buf, varg.len, 0);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001290 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00001291 return pos >= 0;
1292 }
1293 if (ival < 0 || ival >= 256) {
1294 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1295 return -1;
1296 }
1297
1298 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1299}
1300
1301
1302/* Matches the end (direction >= 0) or start (direction < 0) of self
1303 * against substr, using the start and end arguments. Returns
1304 * -1 on error, 0 if not found and 1 if found.
1305 */
1306Py_LOCAL(int)
Benjamin Petersond6720012009-04-18 15:31:34 +00001307_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes44720832008-05-26 13:01:01 +00001308 Py_ssize_t end, int direction)
1309{
1310 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1311 const char* str;
1312 Py_buffer vsubstr;
1313 int rv = 0;
1314
1315 str = PyByteArray_AS_STRING(self);
1316
1317 if (_getbuffer(substr, &vsubstr) < 0)
1318 return -1;
1319
Antoine Pitrou64672132010-01-13 07:55:48 +00001320 ADJUST_INDICES(start, end, len);
Christian Heimes44720832008-05-26 13:01:01 +00001321
1322 if (direction < 0) {
1323 /* startswith */
1324 if (start+vsubstr.len > len) {
1325 goto done;
1326 }
1327 } else {
1328 /* endswith */
1329 if (end-start < vsubstr.len || start > len) {
1330 goto done;
1331 }
1332
1333 if (end-vsubstr.len > start)
1334 start = end - vsubstr.len;
1335 }
1336 if (end-start >= vsubstr.len)
1337 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1338
1339done:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001340 PyBuffer_Release(&vsubstr);
Christian Heimes44720832008-05-26 13:01:01 +00001341 return rv;
1342}
1343
1344
1345PyDoc_STRVAR(startswith__doc__,
1346"B.startswith(prefix [,start [,end]]) -> bool\n\
1347\n\
1348Return True if B starts with the specified prefix, False otherwise.\n\
1349With optional start, test B beginning at that position.\n\
1350With optional end, stop comparing B at that position.\n\
1351prefix can also be a tuple of strings to try.");
1352
1353static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001354bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001355{
1356 Py_ssize_t start = 0;
1357 Py_ssize_t end = PY_SSIZE_T_MAX;
1358 PyObject *subobj;
1359 int result;
1360
Jesus Cea44e81682011-04-20 16:39:15 +02001361 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001362 return NULL;
1363 if (PyTuple_Check(subobj)) {
1364 Py_ssize_t i;
1365 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001366 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001367 PyTuple_GET_ITEM(subobj, i),
1368 start, end, -1);
1369 if (result == -1)
1370 return NULL;
1371 else if (result) {
1372 Py_RETURN_TRUE;
1373 }
1374 }
1375 Py_RETURN_FALSE;
1376 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001377 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001378 if (result == -1)
1379 return NULL;
1380 else
1381 return PyBool_FromLong(result);
1382}
1383
1384PyDoc_STRVAR(endswith__doc__,
1385"B.endswith(suffix [,start [,end]]) -> bool\n\
1386\n\
1387Return True if B ends with the specified suffix, False otherwise.\n\
1388With optional start, test B beginning at that position.\n\
1389With optional end, stop comparing B at that position.\n\
1390suffix can also be a tuple of strings to try.");
1391
1392static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001393bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001394{
1395 Py_ssize_t start = 0;
1396 Py_ssize_t end = PY_SSIZE_T_MAX;
1397 PyObject *subobj;
1398 int result;
1399
Jesus Cea44e81682011-04-20 16:39:15 +02001400 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001401 return NULL;
1402 if (PyTuple_Check(subobj)) {
1403 Py_ssize_t i;
1404 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001405 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001406 PyTuple_GET_ITEM(subobj, i),
1407 start, end, +1);
1408 if (result == -1)
1409 return NULL;
1410 else if (result) {
1411 Py_RETURN_TRUE;
1412 }
1413 }
1414 Py_RETURN_FALSE;
1415 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001416 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001417 if (result == -1)
1418 return NULL;
1419 else
1420 return PyBool_FromLong(result);
1421}
1422
1423
1424PyDoc_STRVAR(translate__doc__,
1425"B.translate(table[, deletechars]) -> bytearray\n\
1426\n\
1427Return a copy of B, where all characters occurring in the\n\
1428optional argument deletechars are removed, and the remaining\n\
1429characters have been mapped through the given translation\n\
1430table, which must be a bytes object of length 256.");
1431
1432static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001433bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001434{
1435 register char *input, *output;
1436 register const char *table;
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001437 register Py_ssize_t i, c;
Christian Heimes44720832008-05-26 13:01:01 +00001438 PyObject *input_obj = (PyObject*)self;
1439 const char *output_start;
1440 Py_ssize_t inlen;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001441 PyObject *result = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001442 int trans_table[256];
Georg Brandl6425a2f2008-12-28 11:54:53 +00001443 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001444 Py_buffer vtable, vdel;
1445
1446 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1447 &tableobj, &delobj))
1448 return NULL;
1449
Georg Brandl6425a2f2008-12-28 11:54:53 +00001450 if (tableobj == Py_None) {
1451 table = NULL;
1452 tableobj = NULL;
1453 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00001454 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001455 } else {
1456 if (vtable.len != 256) {
1457 PyErr_SetString(PyExc_ValueError,
1458 "translation table must be 256 characters long");
Georg Brandlec812ca2009-07-22 11:57:15 +00001459 PyBuffer_Release(&vtable);
1460 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001461 }
1462 table = (const char*)vtable.buf;
Christian Heimes44720832008-05-26 13:01:01 +00001463 }
1464
1465 if (delobj != NULL) {
1466 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandlec812ca2009-07-22 11:57:15 +00001467 if (tableobj != NULL)
1468 PyBuffer_Release(&vtable);
1469 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001470 }
1471 }
1472 else {
1473 vdel.buf = NULL;
1474 vdel.len = 0;
1475 }
1476
Christian Heimes44720832008-05-26 13:01:01 +00001477 inlen = PyByteArray_GET_SIZE(input_obj);
1478 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1479 if (result == NULL)
1480 goto done;
1481 output_start = output = PyByteArray_AsString(result);
1482 input = PyByteArray_AS_STRING(input_obj);
1483
Georg Brandl6425a2f2008-12-28 11:54:53 +00001484 if (vdel.len == 0 && table != NULL) {
Christian Heimes44720832008-05-26 13:01:01 +00001485 /* If no deletions are required, use faster code */
1486 for (i = inlen; --i >= 0; ) {
1487 c = Py_CHARMASK(*input++);
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001488 *output++ = table[c];
Christian Heimes44720832008-05-26 13:01:01 +00001489 }
Christian Heimes44720832008-05-26 13:01:01 +00001490 goto done;
1491 }
Georg Brandl6425a2f2008-12-28 11:54:53 +00001492
1493 if (table == NULL) {
1494 for (i = 0; i < 256; i++)
1495 trans_table[i] = Py_CHARMASK(i);
1496 } else {
1497 for (i = 0; i < 256; i++)
1498 trans_table[i] = Py_CHARMASK(table[i]);
1499 }
Christian Heimes44720832008-05-26 13:01:01 +00001500
1501 for (i = 0; i < vdel.len; i++)
1502 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1503
1504 for (i = inlen; --i >= 0; ) {
1505 c = Py_CHARMASK(*input++);
1506 if (trans_table[c] != -1)
1507 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1508 continue;
Christian Heimes44720832008-05-26 13:01:01 +00001509 }
1510 /* Fix the size of the resulting string */
1511 if (inlen > 0)
1512 PyByteArray_Resize(result, output - output_start);
1513
1514done:
Georg Brandl6425a2f2008-12-28 11:54:53 +00001515 if (tableobj != NULL)
1516 PyBuffer_Release(&vtable);
Christian Heimes44720832008-05-26 13:01:01 +00001517 if (delobj != NULL)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001518 PyBuffer_Release(&vdel);
Christian Heimes44720832008-05-26 13:01:01 +00001519 return result;
1520}
1521
1522
Christian Heimes44720832008-05-26 13:01:01 +00001523/* find and count characters and substrings */
1524
1525#define findchar(target, target_len, c) \
1526 ((char *)memchr((const void *)(target), c, target_len))
1527
Christian Heimes44720832008-05-26 13:01:01 +00001528
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001529/* Bytes ops must return a string, create a copy */
Christian Heimes44720832008-05-26 13:01:01 +00001530Py_LOCAL(PyByteArrayObject *)
1531return_self(PyByteArrayObject *self)
1532{
Christian Heimes44720832008-05-26 13:01:01 +00001533 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1534 PyByteArray_AS_STRING(self),
1535 PyByteArray_GET_SIZE(self));
1536}
1537
1538Py_LOCAL_INLINE(Py_ssize_t)
1539countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1540{
1541 Py_ssize_t count=0;
1542 const char *start=target;
1543 const char *end=target+target_len;
1544
1545 while ( (start=findchar(start, end-start, c)) != NULL ) {
1546 count++;
1547 if (count >= maxcount)
1548 break;
1549 start += 1;
1550 }
1551 return count;
1552}
1553
Christian Heimes44720832008-05-26 13:01:01 +00001554
1555/* Algorithms for different cases of string replacement */
1556
1557/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1558Py_LOCAL(PyByteArrayObject *)
1559replace_interleave(PyByteArrayObject *self,
1560 const char *to_s, Py_ssize_t to_len,
1561 Py_ssize_t maxcount)
1562{
1563 char *self_s, *result_s;
1564 Py_ssize_t self_len, result_len;
1565 Py_ssize_t count, i, product;
1566 PyByteArrayObject *result;
1567
1568 self_len = PyByteArray_GET_SIZE(self);
1569
1570 /* 1 at the end plus 1 after every character */
1571 count = self_len+1;
1572 if (maxcount < count)
1573 count = maxcount;
1574
1575 /* Check for overflow */
1576 /* result_len = count * to_len + self_len; */
1577 product = count * to_len;
1578 if (product / to_len != count) {
1579 PyErr_SetString(PyExc_OverflowError,
1580 "replace string is too long");
1581 return NULL;
1582 }
1583 result_len = product + self_len;
1584 if (result_len < 0) {
1585 PyErr_SetString(PyExc_OverflowError,
1586 "replace string is too long");
1587 return NULL;
1588 }
1589
1590 if (! (result = (PyByteArrayObject *)
1591 PyByteArray_FromStringAndSize(NULL, result_len)) )
1592 return NULL;
1593
1594 self_s = PyByteArray_AS_STRING(self);
1595 result_s = PyByteArray_AS_STRING(result);
1596
1597 /* TODO: special case single character, which doesn't need memcpy */
1598
1599 /* Lay the first one down (guaranteed this will occur) */
1600 Py_MEMCPY(result_s, to_s, to_len);
1601 result_s += to_len;
1602 count -= 1;
1603
1604 for (i=0; i<count; i++) {
1605 *result_s++ = *self_s++;
1606 Py_MEMCPY(result_s, to_s, to_len);
1607 result_s += to_len;
1608 }
1609
1610 /* Copy the rest of the original string */
1611 Py_MEMCPY(result_s, self_s, self_len-i);
1612
1613 return result;
1614}
1615
1616/* Special case for deleting a single character */
1617/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1618Py_LOCAL(PyByteArrayObject *)
1619replace_delete_single_character(PyByteArrayObject *self,
1620 char from_c, Py_ssize_t maxcount)
1621{
1622 char *self_s, *result_s;
1623 char *start, *next, *end;
1624 Py_ssize_t self_len, result_len;
1625 Py_ssize_t count;
1626 PyByteArrayObject *result;
1627
1628 self_len = PyByteArray_GET_SIZE(self);
1629 self_s = PyByteArray_AS_STRING(self);
1630
1631 count = countchar(self_s, self_len, from_c, maxcount);
1632 if (count == 0) {
1633 return return_self(self);
1634 }
1635
1636 result_len = self_len - count; /* from_len == 1 */
1637 assert(result_len>=0);
1638
1639 if ( (result = (PyByteArrayObject *)
1640 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1641 return NULL;
1642 result_s = PyByteArray_AS_STRING(result);
1643
1644 start = self_s;
1645 end = self_s + self_len;
1646 while (count-- > 0) {
1647 next = findchar(start, end-start, from_c);
1648 if (next == NULL)
1649 break;
1650 Py_MEMCPY(result_s, start, next-start);
1651 result_s += (next-start);
1652 start = next+1;
1653 }
1654 Py_MEMCPY(result_s, start, end-start);
1655
1656 return result;
1657}
1658
1659/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1660
1661Py_LOCAL(PyByteArrayObject *)
1662replace_delete_substring(PyByteArrayObject *self,
1663 const char *from_s, Py_ssize_t from_len,
1664 Py_ssize_t maxcount)
1665{
1666 char *self_s, *result_s;
1667 char *start, *next, *end;
1668 Py_ssize_t self_len, result_len;
1669 Py_ssize_t count, offset;
1670 PyByteArrayObject *result;
1671
1672 self_len = PyByteArray_GET_SIZE(self);
1673 self_s = PyByteArray_AS_STRING(self);
1674
Antoine Pitrou64672132010-01-13 07:55:48 +00001675 count = stringlib_count(self_s, self_len,
1676 from_s, from_len,
1677 maxcount);
Christian Heimes44720832008-05-26 13:01:01 +00001678
1679 if (count == 0) {
1680 /* no matches */
1681 return return_self(self);
1682 }
1683
1684 result_len = self_len - (count * from_len);
1685 assert (result_len>=0);
1686
1687 if ( (result = (PyByteArrayObject *)
1688 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1689 return NULL;
1690
1691 result_s = PyByteArray_AS_STRING(result);
1692
1693 start = self_s;
1694 end = self_s + self_len;
1695 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001696 offset = stringlib_find(start, end-start,
1697 from_s, from_len,
1698 0);
Christian Heimes44720832008-05-26 13:01:01 +00001699 if (offset == -1)
1700 break;
1701 next = start + offset;
1702
1703 Py_MEMCPY(result_s, start, next-start);
1704
1705 result_s += (next-start);
1706 start = next+from_len;
1707 }
1708 Py_MEMCPY(result_s, start, end-start);
1709 return result;
1710}
1711
1712/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1713Py_LOCAL(PyByteArrayObject *)
1714replace_single_character_in_place(PyByteArrayObject *self,
1715 char from_c, char to_c,
1716 Py_ssize_t maxcount)
1717{
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001718 char *self_s, *result_s, *start, *end, *next;
1719 Py_ssize_t self_len;
1720 PyByteArrayObject *result;
Christian Heimes44720832008-05-26 13:01:01 +00001721
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001722 /* The result string will be the same size */
1723 self_s = PyByteArray_AS_STRING(self);
1724 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes44720832008-05-26 13:01:01 +00001725
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001726 next = findchar(self_s, self_len, from_c);
Christian Heimes44720832008-05-26 13:01:01 +00001727
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001728 if (next == NULL) {
1729 /* No matches; return the original bytes */
1730 return return_self(self);
1731 }
Christian Heimes44720832008-05-26 13:01:01 +00001732
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001733 /* Need to make a new bytes */
1734 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1735 if (result == NULL)
1736 return NULL;
1737 result_s = PyByteArray_AS_STRING(result);
1738 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes44720832008-05-26 13:01:01 +00001739
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001740 /* change everything in-place, starting with this one */
1741 start = result_s + (next-self_s);
1742 *start = to_c;
1743 start++;
1744 end = result_s + self_len;
Christian Heimes44720832008-05-26 13:01:01 +00001745
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001746 while (--maxcount > 0) {
1747 next = findchar(start, end-start, from_c);
1748 if (next == NULL)
1749 break;
1750 *next = to_c;
1751 start = next+1;
1752 }
Christian Heimes44720832008-05-26 13:01:01 +00001753
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001754 return result;
Christian Heimes44720832008-05-26 13:01:01 +00001755}
1756
1757/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1758Py_LOCAL(PyByteArrayObject *)
1759replace_substring_in_place(PyByteArrayObject *self,
1760 const char *from_s, Py_ssize_t from_len,
1761 const char *to_s, Py_ssize_t to_len,
1762 Py_ssize_t maxcount)
1763{
1764 char *result_s, *start, *end;
1765 char *self_s;
1766 Py_ssize_t self_len, offset;
1767 PyByteArrayObject *result;
1768
1769 /* The result bytes will be the same size */
1770
1771 self_s = PyByteArray_AS_STRING(self);
1772 self_len = PyByteArray_GET_SIZE(self);
1773
Antoine Pitrou64672132010-01-13 07:55:48 +00001774 offset = stringlib_find(self_s, self_len,
1775 from_s, from_len,
1776 0);
Christian Heimes44720832008-05-26 13:01:01 +00001777 if (offset == -1) {
1778 /* No matches; return the original bytes */
1779 return return_self(self);
1780 }
1781
1782 /* Need to make a new bytes */
1783 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1784 if (result == NULL)
1785 return NULL;
1786 result_s = PyByteArray_AS_STRING(result);
1787 Py_MEMCPY(result_s, self_s, self_len);
1788
1789 /* change everything in-place, starting with this one */
1790 start = result_s + offset;
1791 Py_MEMCPY(start, to_s, from_len);
1792 start += from_len;
1793 end = result_s + self_len;
1794
1795 while ( --maxcount > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001796 offset = stringlib_find(start, end-start,
1797 from_s, from_len,
1798 0);
Christian Heimes44720832008-05-26 13:01:01 +00001799 if (offset==-1)
1800 break;
1801 Py_MEMCPY(start+offset, to_s, from_len);
1802 start += offset+from_len;
1803 }
1804
1805 return result;
1806}
1807
1808/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1809Py_LOCAL(PyByteArrayObject *)
1810replace_single_character(PyByteArrayObject *self,
1811 char from_c,
1812 const char *to_s, Py_ssize_t to_len,
1813 Py_ssize_t maxcount)
1814{
1815 char *self_s, *result_s;
1816 char *start, *next, *end;
1817 Py_ssize_t self_len, result_len;
1818 Py_ssize_t count, product;
1819 PyByteArrayObject *result;
1820
1821 self_s = PyByteArray_AS_STRING(self);
1822 self_len = PyByteArray_GET_SIZE(self);
1823
1824 count = countchar(self_s, self_len, from_c, maxcount);
1825 if (count == 0) {
1826 /* no matches, return unchanged */
1827 return return_self(self);
1828 }
1829
1830 /* use the difference between current and new, hence the "-1" */
1831 /* result_len = self_len + count * (to_len-1) */
1832 product = count * (to_len-1);
1833 if (product / (to_len-1) != count) {
1834 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1835 return NULL;
1836 }
1837 result_len = self_len + product;
1838 if (result_len < 0) {
1839 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1840 return NULL;
1841 }
1842
1843 if ( (result = (PyByteArrayObject *)
1844 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1845 return NULL;
1846 result_s = PyByteArray_AS_STRING(result);
1847
1848 start = self_s;
1849 end = self_s + self_len;
1850 while (count-- > 0) {
1851 next = findchar(start, end-start, from_c);
1852 if (next == NULL)
1853 break;
1854
1855 if (next == start) {
1856 /* replace with the 'to' */
1857 Py_MEMCPY(result_s, to_s, to_len);
1858 result_s += to_len;
1859 start += 1;
1860 } else {
1861 /* copy the unchanged old then the 'to' */
1862 Py_MEMCPY(result_s, start, next-start);
1863 result_s += (next-start);
1864 Py_MEMCPY(result_s, to_s, to_len);
1865 result_s += to_len;
1866 start = next+1;
1867 }
1868 }
1869 /* Copy the remainder of the remaining bytes */
1870 Py_MEMCPY(result_s, start, end-start);
1871
1872 return result;
1873}
1874
1875/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1876Py_LOCAL(PyByteArrayObject *)
1877replace_substring(PyByteArrayObject *self,
1878 const char *from_s, Py_ssize_t from_len,
1879 const char *to_s, Py_ssize_t to_len,
1880 Py_ssize_t maxcount)
1881{
1882 char *self_s, *result_s;
1883 char *start, *next, *end;
1884 Py_ssize_t self_len, result_len;
1885 Py_ssize_t count, offset, product;
1886 PyByteArrayObject *result;
1887
1888 self_s = PyByteArray_AS_STRING(self);
1889 self_len = PyByteArray_GET_SIZE(self);
1890
Antoine Pitrou64672132010-01-13 07:55:48 +00001891 count = stringlib_count(self_s, self_len,
1892 from_s, from_len,
1893 maxcount);
1894
Christian Heimes44720832008-05-26 13:01:01 +00001895 if (count == 0) {
1896 /* no matches, return unchanged */
1897 return return_self(self);
1898 }
1899
1900 /* Check for overflow */
1901 /* result_len = self_len + count * (to_len-from_len) */
1902 product = count * (to_len-from_len);
1903 if (product / (to_len-from_len) != count) {
1904 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1905 return NULL;
1906 }
1907 result_len = self_len + product;
1908 if (result_len < 0) {
1909 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1910 return NULL;
1911 }
1912
1913 if ( (result = (PyByteArrayObject *)
1914 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1915 return NULL;
1916 result_s = PyByteArray_AS_STRING(result);
1917
1918 start = self_s;
1919 end = self_s + self_len;
1920 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001921 offset = stringlib_find(start, end-start,
1922 from_s, from_len,
1923 0);
Christian Heimes44720832008-05-26 13:01:01 +00001924 if (offset == -1)
1925 break;
1926 next = start+offset;
1927 if (next == start) {
1928 /* replace with the 'to' */
1929 Py_MEMCPY(result_s, to_s, to_len);
1930 result_s += to_len;
1931 start += from_len;
1932 } else {
1933 /* copy the unchanged old then the 'to' */
1934 Py_MEMCPY(result_s, start, next-start);
1935 result_s += (next-start);
1936 Py_MEMCPY(result_s, to_s, to_len);
1937 result_s += to_len;
1938 start = next+from_len;
1939 }
1940 }
1941 /* Copy the remainder of the remaining bytes */
1942 Py_MEMCPY(result_s, start, end-start);
1943
1944 return result;
1945}
1946
1947
1948Py_LOCAL(PyByteArrayObject *)
1949replace(PyByteArrayObject *self,
1950 const char *from_s, Py_ssize_t from_len,
1951 const char *to_s, Py_ssize_t to_len,
1952 Py_ssize_t maxcount)
1953{
1954 if (maxcount < 0) {
1955 maxcount = PY_SSIZE_T_MAX;
1956 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1957 /* nothing to do; return the original bytes */
1958 return return_self(self);
1959 }
1960
1961 if (maxcount == 0 ||
1962 (from_len == 0 && to_len == 0)) {
1963 /* nothing to do; return the original bytes */
1964 return return_self(self);
1965 }
1966
1967 /* Handle zero-length special cases */
1968
1969 if (from_len == 0) {
1970 /* insert the 'to' bytes everywhere. */
1971 /* >>> "Python".replace("", ".") */
1972 /* '.P.y.t.h.o.n.' */
1973 return replace_interleave(self, to_s, to_len, maxcount);
1974 }
1975
1976 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1977 /* point for an empty self bytes to generate a non-empty bytes */
1978 /* Special case so the remaining code always gets a non-empty bytes */
1979 if (PyByteArray_GET_SIZE(self) == 0) {
1980 return return_self(self);
1981 }
1982
1983 if (to_len == 0) {
1984 /* delete all occurances of 'from' bytes */
1985 if (from_len == 1) {
1986 return replace_delete_single_character(
1987 self, from_s[0], maxcount);
1988 } else {
1989 return replace_delete_substring(self, from_s, from_len, maxcount);
1990 }
1991 }
1992
1993 /* Handle special case where both bytes have the same length */
1994
1995 if (from_len == to_len) {
1996 if (from_len == 1) {
1997 return replace_single_character_in_place(
1998 self,
1999 from_s[0],
2000 to_s[0],
2001 maxcount);
2002 } else {
2003 return replace_substring_in_place(
2004 self, from_s, from_len, to_s, to_len, maxcount);
2005 }
2006 }
2007
2008 /* Otherwise use the more generic algorithms */
2009 if (from_len == 1) {
2010 return replace_single_character(self, from_s[0],
2011 to_s, to_len, maxcount);
2012 } else {
2013 /* len('from')>=2, len('to')>=1 */
2014 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2015 }
2016}
2017
2018
2019PyDoc_STRVAR(replace__doc__,
2020"B.replace(old, new[, count]) -> bytes\n\
2021\n\
2022Return a copy of B with all occurrences of subsection\n\
2023old replaced by new. If the optional argument count is\n\
2024given, only the first count occurrences are replaced.");
2025
2026static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002027bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002028{
2029 Py_ssize_t count = -1;
2030 PyObject *from, *to, *res;
2031 Py_buffer vfrom, vto;
2032
2033 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2034 return NULL;
2035
2036 if (_getbuffer(from, &vfrom) < 0)
2037 return NULL;
2038 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002039 PyBuffer_Release(&vfrom);
Christian Heimes44720832008-05-26 13:01:01 +00002040 return NULL;
2041 }
2042
2043 res = (PyObject *)replace((PyByteArrayObject *) self,
2044 vfrom.buf, vfrom.len,
2045 vto.buf, vto.len, count);
2046
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002047 PyBuffer_Release(&vfrom);
2048 PyBuffer_Release(&vto);
Christian Heimes44720832008-05-26 13:01:01 +00002049 return res;
2050}
2051
Christian Heimes44720832008-05-26 13:01:01 +00002052PyDoc_STRVAR(split__doc__,
2053"B.split([sep[, maxsplit]]) -> list of bytearray\n\
2054\n\
2055Return a list of the sections in B, using sep as the delimiter.\n\
2056If sep is not given, B is split on ASCII whitespace characters\n\
2057(space, tab, return, newline, formfeed, vertical tab).\n\
2058If maxsplit is given, at most maxsplit splits are done.");
2059
2060static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002061bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002062{
Antoine Pitrou64672132010-01-13 07:55:48 +00002063 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2064 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002065 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002066 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002067 Py_buffer vsub;
Christian Heimes44720832008-05-26 13:01:01 +00002068
2069 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2070 return NULL;
2071 if (maxsplit < 0)
2072 maxsplit = PY_SSIZE_T_MAX;
2073
2074 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002075 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002076
2077 if (_getbuffer(subobj, &vsub) < 0)
2078 return NULL;
2079 sub = vsub.buf;
2080 n = vsub.len;
2081
Antoine Pitrou64672132010-01-13 07:55:48 +00002082 list = stringlib_split(
2083 (PyObject*) self, s, len, sub, n, maxsplit
2084 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002085 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002086 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002087}
2088
2089PyDoc_STRVAR(partition__doc__,
2090"B.partition(sep) -> (head, sep, tail)\n\
2091\n\
2092Searches for the separator sep in B, and returns the part before it,\n\
2093the separator itself, and the part after it. If the separator is not\n\
2094found, returns B and two empty bytearray objects.");
2095
2096static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002097bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002098{
2099 PyObject *bytesep, *result;
2100
2101 bytesep = PyByteArray_FromObject(sep_obj);
2102 if (! bytesep)
2103 return NULL;
2104
2105 result = stringlib_partition(
2106 (PyObject*) self,
2107 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2108 bytesep,
2109 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2110 );
2111
2112 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002113 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002114}
2115
2116PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti1fafaab2010-01-25 11:24:37 +00002117"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes44720832008-05-26 13:01:01 +00002118\n\
2119Searches for the separator sep in B, starting at the end of B,\n\
2120and returns the part before it, the separator itself, and the\n\
2121part after it. If the separator is not found, returns two empty\n\
2122bytearray objects and B.");
2123
2124static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002125bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002126{
2127 PyObject *bytesep, *result;
2128
2129 bytesep = PyByteArray_FromObject(sep_obj);
2130 if (! bytesep)
2131 return NULL;
2132
2133 result = stringlib_rpartition(
2134 (PyObject*) self,
2135 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2136 bytesep,
2137 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2138 );
2139
2140 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002141 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002142}
2143
2144PyDoc_STRVAR(rsplit__doc__,
2145"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2146\n\
2147Return a list of the sections in B, using sep as the delimiter,\n\
2148starting at the end of B and working to the front.\n\
2149If sep is not given, B is split on ASCII whitespace characters\n\
2150(space, tab, return, newline, formfeed, vertical tab).\n\
2151If maxsplit is given, at most maxsplit splits are done.");
2152
2153static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002154bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002155{
Antoine Pitrou64672132010-01-13 07:55:48 +00002156 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2157 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002158 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002159 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002160 Py_buffer vsub;
2161
2162 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2163 return NULL;
2164 if (maxsplit < 0)
2165 maxsplit = PY_SSIZE_T_MAX;
2166
2167 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002168 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002169
2170 if (_getbuffer(subobj, &vsub) < 0)
2171 return NULL;
2172 sub = vsub.buf;
2173 n = vsub.len;
2174
Antoine Pitrou64672132010-01-13 07:55:48 +00002175 list = stringlib_rsplit(
2176 (PyObject*) self, s, len, sub, n, maxsplit
2177 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002178 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002179 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002180}
2181
2182PyDoc_STRVAR(reverse__doc__,
2183"B.reverse() -> None\n\
2184\n\
2185Reverse the order of the values in B in place.");
2186static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002187bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes44720832008-05-26 13:01:01 +00002188{
2189 char swap, *head, *tail;
2190 Py_ssize_t i, j, n = Py_SIZE(self);
2191
2192 j = n / 2;
2193 head = self->ob_bytes;
2194 tail = head + n - 1;
2195 for (i = 0; i < j; i++) {
2196 swap = *head;
2197 *head++ = *tail;
2198 *tail-- = swap;
2199 }
2200
2201 Py_RETURN_NONE;
2202}
2203
2204PyDoc_STRVAR(insert__doc__,
2205"B.insert(index, int) -> None\n\
2206\n\
2207Insert a single item into the bytearray before the given index.");
2208static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002209bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002210{
Georg Brandl3e483f62008-07-16 22:57:41 +00002211 PyObject *value;
2212 int ival;
Christian Heimes44720832008-05-26 13:01:01 +00002213 Py_ssize_t where, n = Py_SIZE(self);
2214
Georg Brandl3e483f62008-07-16 22:57:41 +00002215 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes44720832008-05-26 13:01:01 +00002216 return NULL;
2217
2218 if (n == PY_SSIZE_T_MAX) {
2219 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002220 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002221 return NULL;
2222 }
Georg Brandl3e483f62008-07-16 22:57:41 +00002223 if (!_getbytevalue(value, &ival))
Christian Heimes44720832008-05-26 13:01:01 +00002224 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002225 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2226 return NULL;
2227
2228 if (where < 0) {
2229 where += n;
2230 if (where < 0)
2231 where = 0;
2232 }
2233 if (where > n)
2234 where = n;
2235 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl3e483f62008-07-16 22:57:41 +00002236 self->ob_bytes[where] = ival;
Christian Heimes44720832008-05-26 13:01:01 +00002237
2238 Py_RETURN_NONE;
2239}
2240
2241PyDoc_STRVAR(append__doc__,
2242"B.append(int) -> None\n\
2243\n\
2244Append a single item to the end of B.");
2245static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002246bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002247{
2248 int value;
2249 Py_ssize_t n = Py_SIZE(self);
2250
2251 if (! _getbytevalue(arg, &value))
2252 return NULL;
2253 if (n == PY_SSIZE_T_MAX) {
2254 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002255 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002256 return NULL;
2257 }
2258 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2259 return NULL;
2260
2261 self->ob_bytes[n] = value;
2262
2263 Py_RETURN_NONE;
2264}
2265
2266PyDoc_STRVAR(extend__doc__,
2267"B.extend(iterable int) -> None\n\
2268\n\
2269Append all the elements from the iterator or sequence to the\n\
2270end of B.");
2271static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002272bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002273{
Benjamin Petersond6720012009-04-18 15:31:34 +00002274 PyObject *it, *item, *bytearray_obj;
Christian Heimes44720832008-05-26 13:01:01 +00002275 Py_ssize_t buf_size = 0, len = 0;
2276 int value;
2277 char *buf;
2278
Benjamin Petersond6720012009-04-18 15:31:34 +00002279 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes44720832008-05-26 13:01:01 +00002280 if (PyObject_CheckBuffer(arg)) {
Benjamin Petersond6720012009-04-18 15:31:34 +00002281 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002282 return NULL;
2283
2284 Py_RETURN_NONE;
2285 }
2286
2287 it = PyObject_GetIter(arg);
2288 if (it == NULL)
2289 return NULL;
2290
Ezio Melotti24b07bc2011-03-15 18:55:01 +02002291 /* Try to determine the length of the argument. 32 is arbitrary. */
Christian Heimes44720832008-05-26 13:01:01 +00002292 buf_size = _PyObject_LengthHint(arg, 32);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002293 if (buf_size == -1) {
2294 Py_DECREF(it);
2295 return NULL;
2296 }
Christian Heimes44720832008-05-26 13:01:01 +00002297
Benjamin Petersond6720012009-04-18 15:31:34 +00002298 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2299 if (bytearray_obj == NULL)
Christian Heimes44720832008-05-26 13:01:01 +00002300 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002301 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002302
2303 while ((item = PyIter_Next(it)) != NULL) {
2304 if (! _getbytevalue(item, &value)) {
2305 Py_DECREF(item);
2306 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002307 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002308 return NULL;
2309 }
2310 buf[len++] = value;
2311 Py_DECREF(item);
2312
2313 if (len >= buf_size) {
2314 buf_size = len + (len >> 1) + 1;
Benjamin Petersond6720012009-04-18 15:31:34 +00002315 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00002316 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002317 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002318 return NULL;
2319 }
2320 /* Recompute the `buf' pointer, since the resizing operation may
2321 have invalidated it. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002322 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002323 }
2324 }
2325 Py_DECREF(it);
2326
2327 /* Resize down to exact size. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002328 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2329 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002330 return NULL;
2331 }
2332
Benjamin Petersond6720012009-04-18 15:31:34 +00002333 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002334 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002335 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002336
2337 Py_RETURN_NONE;
2338}
2339
2340PyDoc_STRVAR(pop__doc__,
2341"B.pop([index]) -> int\n\
2342\n\
2343Remove and return a single item from B. If no index\n\
Andrew M. Kuchlingd8972642008-06-21 13:29:12 +00002344argument is given, will pop the last value.");
Christian Heimes44720832008-05-26 13:01:01 +00002345static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002346bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002347{
2348 int value;
2349 Py_ssize_t where = -1, n = Py_SIZE(self);
2350
2351 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2352 return NULL;
2353
2354 if (n == 0) {
Eli Bendersky680e6eb2011-03-04 06:14:56 +00002355 PyErr_SetString(PyExc_IndexError,
2356 "pop from empty bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002357 return NULL;
2358 }
2359 if (where < 0)
2360 where += Py_SIZE(self);
2361 if (where < 0 || where >= Py_SIZE(self)) {
2362 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2363 return NULL;
2364 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002365 if (!_canresize(self))
2366 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002367
2368 value = self->ob_bytes[where];
2369 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2370 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2371 return NULL;
2372
Mark Dickinsonc8a7c7c2009-09-06 10:03:31 +00002373 return PyInt_FromLong((unsigned char)value);
Christian Heimes44720832008-05-26 13:01:01 +00002374}
2375
2376PyDoc_STRVAR(remove__doc__,
2377"B.remove(int) -> None\n\
2378\n\
2379Remove the first occurance of a value in B.");
2380static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002381bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002382{
2383 int value;
2384 Py_ssize_t where, n = Py_SIZE(self);
2385
2386 if (! _getbytevalue(arg, &value))
2387 return NULL;
2388
2389 for (where = 0; where < n; where++) {
2390 if (self->ob_bytes[where] == value)
2391 break;
2392 }
2393 if (where == n) {
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002394 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002395 return NULL;
2396 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002397 if (!_canresize(self))
2398 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002399
2400 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2401 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2402 return NULL;
2403
2404 Py_RETURN_NONE;
2405}
2406
2407/* XXX These two helpers could be optimized if argsize == 1 */
2408
2409static Py_ssize_t
2410lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2411 void *argptr, Py_ssize_t argsize)
2412{
2413 Py_ssize_t i = 0;
2414 while (i < mysize && memchr(argptr, myptr[i], argsize))
2415 i++;
2416 return i;
2417}
2418
2419static Py_ssize_t
2420rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2421 void *argptr, Py_ssize_t argsize)
2422{
2423 Py_ssize_t i = mysize - 1;
2424 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2425 i--;
2426 return i + 1;
2427}
2428
2429PyDoc_STRVAR(strip__doc__,
2430"B.strip([bytes]) -> bytearray\n\
2431\n\
2432Strip leading and trailing bytes contained in the argument.\n\
2433If the argument is omitted, strip ASCII whitespace.");
2434static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002435bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002436{
2437 Py_ssize_t left, right, mysize, argsize;
2438 void *myptr, *argptr;
2439 PyObject *arg = Py_None;
2440 Py_buffer varg;
2441 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2442 return NULL;
2443 if (arg == Py_None) {
2444 argptr = "\t\n\r\f\v ";
2445 argsize = 6;
2446 }
2447 else {
2448 if (_getbuffer(arg, &varg) < 0)
2449 return NULL;
2450 argptr = varg.buf;
2451 argsize = varg.len;
2452 }
2453 myptr = self->ob_bytes;
2454 mysize = Py_SIZE(self);
2455 left = lstrip_helper(myptr, mysize, argptr, argsize);
2456 if (left == mysize)
2457 right = left;
2458 else
2459 right = rstrip_helper(myptr, mysize, argptr, argsize);
2460 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002461 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002462 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2463}
2464
2465PyDoc_STRVAR(lstrip__doc__,
2466"B.lstrip([bytes]) -> bytearray\n\
2467\n\
2468Strip leading bytes contained in the argument.\n\
2469If the argument is omitted, strip leading ASCII whitespace.");
2470static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002471bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002472{
2473 Py_ssize_t left, right, mysize, argsize;
2474 void *myptr, *argptr;
2475 PyObject *arg = Py_None;
2476 Py_buffer varg;
2477 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2478 return NULL;
2479 if (arg == Py_None) {
2480 argptr = "\t\n\r\f\v ";
2481 argsize = 6;
2482 }
2483 else {
2484 if (_getbuffer(arg, &varg) < 0)
2485 return NULL;
2486 argptr = varg.buf;
2487 argsize = varg.len;
2488 }
2489 myptr = self->ob_bytes;
2490 mysize = Py_SIZE(self);
2491 left = lstrip_helper(myptr, mysize, argptr, argsize);
2492 right = mysize;
2493 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002494 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002495 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2496}
2497
2498PyDoc_STRVAR(rstrip__doc__,
2499"B.rstrip([bytes]) -> bytearray\n\
2500\n\
2501Strip trailing bytes contained in the argument.\n\
2502If the argument is omitted, strip trailing ASCII whitespace.");
2503static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002504bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002505{
2506 Py_ssize_t left, right, mysize, argsize;
2507 void *myptr, *argptr;
2508 PyObject *arg = Py_None;
2509 Py_buffer varg;
2510 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2511 return NULL;
2512 if (arg == Py_None) {
2513 argptr = "\t\n\r\f\v ";
2514 argsize = 6;
2515 }
2516 else {
2517 if (_getbuffer(arg, &varg) < 0)
2518 return NULL;
2519 argptr = varg.buf;
2520 argsize = varg.len;
2521 }
2522 myptr = self->ob_bytes;
2523 mysize = Py_SIZE(self);
2524 left = 0;
2525 right = rstrip_helper(myptr, mysize, argptr, argsize);
2526 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002527 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002528 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2529}
2530
2531PyDoc_STRVAR(decode_doc,
2532"B.decode([encoding[, errors]]) -> unicode object.\n\
2533\n\
2534Decodes B using the codec registered for encoding. encoding defaults\n\
2535to the default encoding. errors may be given to set a different error\n\
2536handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2537a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2538as well as any other name registered with codecs.register_error that is\n\
2539able to handle UnicodeDecodeErrors.");
2540
2541static PyObject *
Benjamin Petersondc782b52009-09-18 21:46:21 +00002542bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes44720832008-05-26 13:01:01 +00002543{
2544 const char *encoding = NULL;
2545 const char *errors = NULL;
Benjamin Petersondc782b52009-09-18 21:46:21 +00002546 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes44720832008-05-26 13:01:01 +00002547
Benjamin Petersondc782b52009-09-18 21:46:21 +00002548 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes44720832008-05-26 13:01:01 +00002549 return NULL;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002550 if (encoding == NULL) {
2551#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002552 encoding = PyUnicode_GetDefaultEncoding();
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002553#else
2554 PyErr_SetString(PyExc_ValueError, "no encoding specified");
2555 return NULL;
2556#endif
2557 }
Christian Heimes44720832008-05-26 13:01:01 +00002558 return PyCodec_Decode(self, encoding, errors);
2559}
2560
2561PyDoc_STRVAR(alloc_doc,
2562"B.__alloc__() -> int\n\
2563\n\
2564Returns the number of bytes actually allocated.");
2565
2566static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002567bytearray_alloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002568{
2569 return PyInt_FromSsize_t(self->ob_alloc);
2570}
2571
2572PyDoc_STRVAR(join_doc,
2573"B.join(iterable_of_bytes) -> bytes\n\
2574\n\
2575Concatenates any number of bytearray objects, with B in between each pair.");
2576
2577static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002578bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002579{
2580 PyObject *seq;
2581 Py_ssize_t mysize = Py_SIZE(self);
2582 Py_ssize_t i;
2583 Py_ssize_t n;
2584 PyObject **items;
2585 Py_ssize_t totalsize = 0;
2586 PyObject *result;
2587 char *dest;
2588
2589 seq = PySequence_Fast(it, "can only join an iterable");
2590 if (seq == NULL)
2591 return NULL;
2592 n = PySequence_Fast_GET_SIZE(seq);
2593 items = PySequence_Fast_ITEMS(seq);
2594
2595 /* Compute the total size, and check that they are all bytes */
2596 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2597 for (i = 0; i < n; i++) {
2598 PyObject *obj = items[i];
2599 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2600 PyErr_Format(PyExc_TypeError,
2601 "can only join an iterable of bytes "
2602 "(item %ld has type '%.100s')",
2603 /* XXX %ld isn't right on Win64 */
2604 (long)i, Py_TYPE(obj)->tp_name);
2605 goto error;
2606 }
2607 if (i > 0)
2608 totalsize += mysize;
2609 totalsize += Py_SIZE(obj);
2610 if (totalsize < 0) {
2611 PyErr_NoMemory();
2612 goto error;
2613 }
2614 }
2615
2616 /* Allocate the result, and copy the bytes */
2617 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2618 if (result == NULL)
2619 goto error;
2620 dest = PyByteArray_AS_STRING(result);
2621 for (i = 0; i < n; i++) {
2622 PyObject *obj = items[i];
2623 Py_ssize_t size = Py_SIZE(obj);
2624 char *buf;
2625 if (PyByteArray_Check(obj))
2626 buf = PyByteArray_AS_STRING(obj);
2627 else
2628 buf = PyBytes_AS_STRING(obj);
2629 if (i) {
2630 memcpy(dest, self->ob_bytes, mysize);
2631 dest += mysize;
2632 }
2633 memcpy(dest, buf, size);
2634 dest += size;
2635 }
2636
2637 /* Done */
2638 Py_DECREF(seq);
2639 return result;
2640
2641 /* Error handling */
2642 error:
2643 Py_DECREF(seq);
2644 return NULL;
2645}
2646
Antoine Pitrou64672132010-01-13 07:55:48 +00002647PyDoc_STRVAR(splitlines__doc__,
2648"B.splitlines([keepends]) -> list of lines\n\
2649\n\
2650Return a list of the lines in B, breaking at line boundaries.\n\
2651Line breaks are not included in the resulting list unless keepends\n\
2652is given and true.");
2653
2654static PyObject*
2655bytearray_splitlines(PyObject *self, PyObject *args)
2656{
2657 int keepends = 0;
2658
2659 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2660 return NULL;
2661
2662 return stringlib_splitlines(
2663 (PyObject*) self, PyByteArray_AS_STRING(self),
2664 PyByteArray_GET_SIZE(self), keepends
2665 );
2666}
2667
Christian Heimes44720832008-05-26 13:01:01 +00002668PyDoc_STRVAR(fromhex_doc,
2669"bytearray.fromhex(string) -> bytearray\n\
2670\n\
2671Create a bytearray object from a string of hexadecimal numbers.\n\
2672Spaces between two numbers are accepted.\n\
2673Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2674
2675static int
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002676hex_digit_to_int(char c)
Christian Heimes44720832008-05-26 13:01:01 +00002677{
Eric Smithcac7af62009-04-27 19:04:37 +00002678 if (Py_ISDIGIT(c))
Christian Heimes44720832008-05-26 13:01:01 +00002679 return c - '0';
2680 else {
Eric Smithcac7af62009-04-27 19:04:37 +00002681 if (Py_ISUPPER(c))
2682 c = Py_TOLOWER(c);
Christian Heimes44720832008-05-26 13:01:01 +00002683 if (c >= 'a' && c <= 'f')
2684 return c - 'a' + 10;
2685 }
2686 return -1;
2687}
2688
2689static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002690bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002691{
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002692 PyObject *newbytes;
Christian Heimes44720832008-05-26 13:01:01 +00002693 char *buf;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002694 char *hex;
Christian Heimes44720832008-05-26 13:01:01 +00002695 Py_ssize_t hexlen, byteslen, i, j;
2696 int top, bot;
2697
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002698 if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
Christian Heimes44720832008-05-26 13:01:01 +00002699 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002700 byteslen = hexlen/2; /* This overestimates if there are spaces */
2701 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2702 if (!newbytes)
2703 return NULL;
2704 buf = PyByteArray_AS_STRING(newbytes);
2705 for (i = j = 0; i < hexlen; i += 2) {
2706 /* skip over spaces in the input */
2707 while (hex[i] == ' ')
2708 i++;
2709 if (i >= hexlen)
2710 break;
2711 top = hex_digit_to_int(hex[i]);
2712 bot = hex_digit_to_int(hex[i+1]);
2713 if (top == -1 || bot == -1) {
2714 PyErr_Format(PyExc_ValueError,
2715 "non-hexadecimal number found in "
2716 "fromhex() arg at position %zd", i);
2717 goto error;
2718 }
2719 buf[j++] = (top << 4) + bot;
2720 }
2721 if (PyByteArray_Resize(newbytes, j) < 0)
2722 goto error;
2723 return newbytes;
2724
2725 error:
2726 Py_DECREF(newbytes);
2727 return NULL;
2728}
2729
2730PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2731
2732static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002733bytearray_reduce(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002734{
2735 PyObject *latin1, *dict;
2736 if (self->ob_bytes)
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002737#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002738 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2739 Py_SIZE(self), NULL);
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002740#else
Mark Dickinson9d109742009-10-15 15:18:55 +00002741 latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002742#endif
Christian Heimes44720832008-05-26 13:01:01 +00002743 else
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002744#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002745 latin1 = PyUnicode_FromString("");
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002746#else
2747 latin1 = PyString_FromString("");
2748#endif
Christian Heimes44720832008-05-26 13:01:01 +00002749
2750 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2751 if (dict == NULL) {
2752 PyErr_Clear();
2753 dict = Py_None;
2754 Py_INCREF(dict);
2755 }
2756
2757 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2758}
2759
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002760PyDoc_STRVAR(sizeof_doc,
2761"B.__sizeof__() -> int\n\
2762 \n\
2763Returns the size of B in memory, in bytes");
2764static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002765bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002766{
Georg Brandl517cfdc2009-04-05 13:16:35 +00002767 Py_ssize_t res;
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002768
Georg Brandl517cfdc2009-04-05 13:16:35 +00002769 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2770 return PyInt_FromSsize_t(res);
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002771}
2772
Benjamin Petersond6720012009-04-18 15:31:34 +00002773static PySequenceMethods bytearray_as_sequence = {
2774 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes44720832008-05-26 13:01:01 +00002775 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Petersond6720012009-04-18 15:31:34 +00002776 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2777 (ssizeargfunc)bytearray_getitem, /* sq_item */
2778 0, /* sq_slice */
2779 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2780 0, /* sq_ass_slice */
2781 (objobjproc)bytearray_contains, /* sq_contains */
2782 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2783 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes44720832008-05-26 13:01:01 +00002784};
2785
Benjamin Petersond6720012009-04-18 15:31:34 +00002786static PyMappingMethods bytearray_as_mapping = {
2787 (lenfunc)bytearray_length,
2788 (binaryfunc)bytearray_subscript,
2789 (objobjargproc)bytearray_ass_subscript,
Christian Heimes44720832008-05-26 13:01:01 +00002790};
2791
Benjamin Petersond6720012009-04-18 15:31:34 +00002792static PyBufferProcs bytearray_as_buffer = {
2793 (readbufferproc)bytearray_buffer_getreadbuf,
2794 (writebufferproc)bytearray_buffer_getwritebuf,
2795 (segcountproc)bytearray_buffer_getsegcount,
2796 (charbufferproc)bytearray_buffer_getcharbuf,
2797 (getbufferproc)bytearray_getbuffer,
2798 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes44720832008-05-26 13:01:01 +00002799};
2800
2801static PyMethodDef
Benjamin Petersond6720012009-04-18 15:31:34 +00002802bytearray_methods[] = {
2803 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2804 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2805 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2806 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002807 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2808 _Py_capitalize__doc__},
2809 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002810 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Petersondc782b52009-09-18 21:46:21 +00002811 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002812 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002813 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2814 expandtabs__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002815 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2816 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2817 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes44720832008-05-26 13:01:01 +00002818 fromhex_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002819 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2820 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002821 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2822 _Py_isalnum__doc__},
2823 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2824 _Py_isalpha__doc__},
2825 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2826 _Py_isdigit__doc__},
2827 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2828 _Py_islower__doc__},
2829 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2830 _Py_isspace__doc__},
2831 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2832 _Py_istitle__doc__},
2833 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2834 _Py_isupper__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002835 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes44720832008-05-26 13:01:01 +00002836 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2837 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002838 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2839 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2840 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2841 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2842 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2843 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2844 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2845 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002846 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002847 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2848 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2849 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2850 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrou64672132010-01-13 07:55:48 +00002851 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002852 splitlines__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002853 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes44720832008-05-26 13:01:01 +00002854 startswith__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002855 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002856 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2857 _Py_swapcase__doc__},
2858 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002859 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002860 translate__doc__},
2861 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2862 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2863 {NULL}
2864};
2865
Benjamin Petersond6720012009-04-18 15:31:34 +00002866PyDoc_STRVAR(bytearray_doc,
Christian Heimes44720832008-05-26 13:01:01 +00002867"bytearray(iterable_of_ints) -> bytearray.\n\
2868bytearray(string, encoding[, errors]) -> bytearray.\n\
2869bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
2870bytearray(memory_view) -> bytearray.\n\
2871\n\
2872Construct an mutable bytearray object from:\n\
2873 - an iterable yielding integers in range(256)\n\
2874 - a text string encoded using the specified encoding\n\
2875 - a bytes or a bytearray object\n\
2876 - any object implementing the buffer API.\n\
2877\n\
2878bytearray(int) -> bytearray.\n\
2879\n\
2880Construct a zero-initialized bytearray of the given length.");
2881
2882
Benjamin Petersond6720012009-04-18 15:31:34 +00002883static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes44720832008-05-26 13:01:01 +00002884
2885PyTypeObject PyByteArray_Type = {
2886 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2887 "bytearray",
2888 sizeof(PyByteArrayObject),
2889 0,
Benjamin Petersond6720012009-04-18 15:31:34 +00002890 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00002891 0, /* tp_print */
2892 0, /* tp_getattr */
2893 0, /* tp_setattr */
2894 0, /* tp_compare */
Benjamin Petersond6720012009-04-18 15:31:34 +00002895 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes44720832008-05-26 13:01:01 +00002896 0, /* tp_as_number */
Benjamin Petersond6720012009-04-18 15:31:34 +00002897 &bytearray_as_sequence, /* tp_as_sequence */
2898 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes44720832008-05-26 13:01:01 +00002899 0, /* tp_hash */
2900 0, /* tp_call */
Benjamin Petersond6720012009-04-18 15:31:34 +00002901 bytearray_str, /* tp_str */
Christian Heimes44720832008-05-26 13:01:01 +00002902 PyObject_GenericGetAttr, /* tp_getattro */
2903 0, /* tp_setattro */
Benjamin Petersond6720012009-04-18 15:31:34 +00002904 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes44720832008-05-26 13:01:01 +00002905 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2906 Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
Benjamin Petersond6720012009-04-18 15:31:34 +00002907 bytearray_doc, /* tp_doc */
Christian Heimes44720832008-05-26 13:01:01 +00002908 0, /* tp_traverse */
2909 0, /* tp_clear */
Benjamin Petersond6720012009-04-18 15:31:34 +00002910 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes44720832008-05-26 13:01:01 +00002911 0, /* tp_weaklistoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002912 bytearray_iter, /* tp_iter */
Christian Heimes44720832008-05-26 13:01:01 +00002913 0, /* tp_iternext */
Benjamin Petersond6720012009-04-18 15:31:34 +00002914 bytearray_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00002915 0, /* tp_members */
2916 0, /* tp_getset */
2917 0, /* tp_base */
2918 0, /* tp_dict */
2919 0, /* tp_descr_get */
2920 0, /* tp_descr_set */
2921 0, /* tp_dictoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002922 (initproc)bytearray_init, /* tp_init */
Christian Heimes44720832008-05-26 13:01:01 +00002923 PyType_GenericAlloc, /* tp_alloc */
2924 PyType_GenericNew, /* tp_new */
2925 PyObject_Del, /* tp_free */
2926};
2927
2928/*********************** Bytes Iterator ****************************/
2929
2930typedef struct {
2931 PyObject_HEAD
2932 Py_ssize_t it_index;
2933 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2934} bytesiterobject;
2935
2936static void
Benjamin Petersond6720012009-04-18 15:31:34 +00002937bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002938{
2939 _PyObject_GC_UNTRACK(it);
2940 Py_XDECREF(it->it_seq);
2941 PyObject_GC_Del(it);
2942}
2943
2944static int
Benjamin Petersond6720012009-04-18 15:31:34 +00002945bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002946{
2947 Py_VISIT(it->it_seq);
2948 return 0;
2949}
2950
2951static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002952bytearrayiter_next(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002953{
2954 PyByteArrayObject *seq;
2955 PyObject *item;
2956
2957 assert(it != NULL);
2958 seq = it->it_seq;
2959 if (seq == NULL)
2960 return NULL;
2961 assert(PyByteArray_Check(seq));
2962
2963 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2964 item = PyInt_FromLong(
2965 (unsigned char)seq->ob_bytes[it->it_index]);
2966 if (item != NULL)
2967 ++it->it_index;
2968 return item;
2969 }
2970
2971 Py_DECREF(seq);
2972 it->it_seq = NULL;
2973 return NULL;
2974}
2975
2976static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002977bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002978{
2979 Py_ssize_t len = 0;
2980 if (it->it_seq)
2981 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2982 return PyInt_FromSsize_t(len);
2983}
2984
2985PyDoc_STRVAR(length_hint_doc,
2986 "Private method returning an estimate of len(list(it)).");
2987
Benjamin Petersond6720012009-04-18 15:31:34 +00002988static PyMethodDef bytearrayiter_methods[] = {
2989 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002990 length_hint_doc},
2991 {NULL, NULL} /* sentinel */
2992};
2993
2994PyTypeObject PyByteArrayIter_Type = {
2995 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2996 "bytearray_iterator", /* tp_name */
2997 sizeof(bytesiterobject), /* tp_basicsize */
2998 0, /* tp_itemsize */
2999 /* methods */
Benjamin Petersond6720012009-04-18 15:31:34 +00003000 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00003001 0, /* tp_print */
3002 0, /* tp_getattr */
3003 0, /* tp_setattr */
3004 0, /* tp_compare */
3005 0, /* tp_repr */
3006 0, /* tp_as_number */
3007 0, /* tp_as_sequence */
3008 0, /* tp_as_mapping */
3009 0, /* tp_hash */
3010 0, /* tp_call */
3011 0, /* tp_str */
3012 PyObject_GenericGetAttr, /* tp_getattro */
3013 0, /* tp_setattro */
3014 0, /* tp_as_buffer */
3015 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3016 0, /* tp_doc */
Benjamin Petersond6720012009-04-18 15:31:34 +00003017 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes44720832008-05-26 13:01:01 +00003018 0, /* tp_clear */
3019 0, /* tp_richcompare */
3020 0, /* tp_weaklistoffset */
3021 PyObject_SelfIter, /* tp_iter */
Benjamin Petersond6720012009-04-18 15:31:34 +00003022 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3023 bytearrayiter_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00003024 0,
3025};
3026
3027static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003028bytearray_iter(PyObject *seq)
Christian Heimes44720832008-05-26 13:01:01 +00003029{
3030 bytesiterobject *it;
3031
3032 if (!PyByteArray_Check(seq)) {
3033 PyErr_BadInternalCall();
3034 return NULL;
3035 }
3036 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3037 if (it == NULL)
3038 return NULL;
3039 it->it_index = 0;
3040 Py_INCREF(seq);
3041 it->it_seq = (PyByteArrayObject *)seq;
3042 _PyObject_GC_TRACK(it);
3043 return (PyObject *)it;
3044}