blob: fdeec4cf7a3fcae45fd0db58b27f34a980aebe6a [file] [log] [blame]
Christian Heimes44720832008-05-26 13:01:01 +00001/* PyBytes (bytearray) implementation */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
5#include "structmember.h"
6#include "bytes_methods.h"
7
Antoine Pitroue80a6a42010-01-17 12:26:20 +00008char _PyByteArray_empty_string[] = "";
Christian Heimes44720832008-05-26 13:01:01 +00009
10void
11PyByteArray_Fini(void)
12{
Christian Heimes44720832008-05-26 13:01:01 +000013}
14
15int
16PyByteArray_Init(void)
17{
Christian Heimes44720832008-05-26 13:01:01 +000018 return 1;
19}
20
21/* end nullbytes support */
22
23/* Helpers */
24
25static int
26_getbytevalue(PyObject* arg, int *value)
27{
28 long face_value;
29
Georg Brandl3e483f62008-07-16 22:57:41 +000030 if (PyBytes_CheckExact(arg)) {
Christian Heimes44720832008-05-26 13:01:01 +000031 if (Py_SIZE(arg) != 1) {
32 PyErr_SetString(PyExc_ValueError, "string must be of size 1");
33 return 0;
34 }
Georg Brandl3e483f62008-07-16 22:57:41 +000035 *value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
36 return 1;
37 }
38 else if (PyInt_Check(arg) || PyLong_Check(arg)) {
39 face_value = PyLong_AsLong(arg);
Christian Heimes44720832008-05-26 13:01:01 +000040 }
41 else {
Georg Brandl3e483f62008-07-16 22:57:41 +000042 PyObject *index = PyNumber_Index(arg);
43 if (index == NULL) {
44 PyErr_Format(PyExc_TypeError,
45 "an integer or string of size 1 is required");
46 return 0;
47 }
48 face_value = PyLong_AsLong(index);
49 Py_DECREF(index);
50 }
Georg Brandl3e483f62008-07-16 22:57:41 +000051
52 if (face_value < 0 || face_value >= 256) {
Georg Brandl3238a3e2008-07-16 23:17:46 +000053 /* this includes the OverflowError in case the long is too large */
Georg Brandl3e483f62008-07-16 22:57:41 +000054 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Christian Heimes44720832008-05-26 13:01:01 +000055 return 0;
56 }
57
58 *value = face_value;
59 return 1;
60}
61
62static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000063bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000064{
65 if ( index != 0 ) {
66 PyErr_SetString(PyExc_SystemError,
67 "accessing non-existent bytes segment");
68 return -1;
69 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +000070 *ptr = (void *)PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +000071 return Py_SIZE(self);
72}
73
74static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000075bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000076{
77 if ( index != 0 ) {
78 PyErr_SetString(PyExc_SystemError,
79 "accessing non-existent bytes segment");
80 return -1;
81 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +000082 *ptr = (void *)PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +000083 return Py_SIZE(self);
84}
85
86static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000087bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
Christian Heimes44720832008-05-26 13:01:01 +000088{
89 if ( lenp )
90 *lenp = Py_SIZE(self);
91 return 1;
92}
93
94static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000095bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000096{
97 if ( index != 0 ) {
98 PyErr_SetString(PyExc_SystemError,
99 "accessing non-existent bytes segment");
100 return -1;
101 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000102 *ptr = PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +0000103 return Py_SIZE(self);
104}
105
106static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000107bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes44720832008-05-26 13:01:01 +0000108{
109 int ret;
110 void *ptr;
111 if (view == NULL) {
112 obj->ob_exports++;
113 return 0;
114 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000115 ptr = (void *) PyByteArray_AS_STRING(obj);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000116 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
Christian Heimes44720832008-05-26 13:01:01 +0000117 if (ret >= 0) {
118 obj->ob_exports++;
119 }
120 return ret;
121}
122
123static void
Benjamin Petersond6720012009-04-18 15:31:34 +0000124bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes44720832008-05-26 13:01:01 +0000125{
126 obj->ob_exports--;
127}
128
129static Py_ssize_t
130_getbuffer(PyObject *obj, Py_buffer *view)
131{
132 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
133
134 if (buffer == NULL || buffer->bf_getbuffer == NULL)
135 {
136 PyErr_Format(PyExc_TypeError,
137 "Type %.100s doesn't support the buffer API",
138 Py_TYPE(obj)->tp_name);
139 return -1;
140 }
141
142 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
143 return -1;
144 return view->len;
145}
146
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000147static int
148_canresize(PyByteArrayObject *self)
149{
150 if (self->ob_exports > 0) {
151 PyErr_SetString(PyExc_BufferError,
152 "Existing exports of data: object cannot be re-sized");
153 return 0;
154 }
155 return 1;
156}
157
Christian Heimes44720832008-05-26 13:01:01 +0000158/* Direct API functions */
159
160PyObject *
161PyByteArray_FromObject(PyObject *input)
162{
163 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
164 input, NULL);
165}
166
167PyObject *
168PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
169{
170 PyByteArrayObject *new;
171 Py_ssize_t alloc;
172
173 if (size < 0) {
174 PyErr_SetString(PyExc_SystemError,
175 "Negative size passed to PyByteArray_FromStringAndSize");
176 return NULL;
177 }
178
179 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
180 if (new == NULL)
181 return NULL;
182
183 if (size == 0) {
184 new->ob_bytes = NULL;
185 alloc = 0;
186 }
187 else {
188 alloc = size + 1;
189 new->ob_bytes = PyMem_Malloc(alloc);
190 if (new->ob_bytes == NULL) {
191 Py_DECREF(new);
192 return PyErr_NoMemory();
193 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000194 if (bytes != NULL && size > 0)
Christian Heimes44720832008-05-26 13:01:01 +0000195 memcpy(new->ob_bytes, bytes, size);
196 new->ob_bytes[size] = '\0'; /* Trailing null byte */
197 }
198 Py_SIZE(new) = size;
199 new->ob_alloc = alloc;
200 new->ob_exports = 0;
201
202 return (PyObject *)new;
203}
204
205Py_ssize_t
206PyByteArray_Size(PyObject *self)
207{
208 assert(self != NULL);
209 assert(PyByteArray_Check(self));
210
211 return PyByteArray_GET_SIZE(self);
212}
213
214char *
215PyByteArray_AsString(PyObject *self)
216{
217 assert(self != NULL);
218 assert(PyByteArray_Check(self));
219
220 return PyByteArray_AS_STRING(self);
221}
222
223int
224PyByteArray_Resize(PyObject *self, Py_ssize_t size)
225{
226 void *sval;
227 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
228
229 assert(self != NULL);
230 assert(PyByteArray_Check(self));
231 assert(size >= 0);
232
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000233 if (size == Py_SIZE(self)) {
234 return 0;
235 }
236 if (!_canresize((PyByteArrayObject *)self)) {
237 return -1;
238 }
239
Christian Heimes44720832008-05-26 13:01:01 +0000240 if (size < alloc / 2) {
241 /* Major downsize; resize down to exact size */
242 alloc = size + 1;
243 }
244 else if (size < alloc) {
245 /* Within allocated size; quick exit */
246 Py_SIZE(self) = size;
247 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
248 return 0;
249 }
250 else if (size <= alloc * 1.125) {
251 /* Moderate upsize; overallocate similar to list_resize() */
252 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
253 }
254 else {
255 /* Major upsize; resize up to exact size */
256 alloc = size + 1;
257 }
258
Christian Heimes44720832008-05-26 13:01:01 +0000259 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
260 if (sval == NULL) {
261 PyErr_NoMemory();
262 return -1;
263 }
264
265 ((PyByteArrayObject *)self)->ob_bytes = sval;
266 Py_SIZE(self) = size;
267 ((PyByteArrayObject *)self)->ob_alloc = alloc;
268 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
269
270 return 0;
271}
272
273PyObject *
274PyByteArray_Concat(PyObject *a, PyObject *b)
275{
276 Py_ssize_t size;
277 Py_buffer va, vb;
278 PyByteArrayObject *result = NULL;
279
280 va.len = -1;
281 vb.len = -1;
282 if (_getbuffer(a, &va) < 0 ||
283 _getbuffer(b, &vb) < 0) {
284 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
285 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
286 goto done;
287 }
288
289 size = va.len + vb.len;
290 if (size < 0) {
Hirokazu Yamamotoa3e6c972009-03-05 09:34:14 +0000291 PyErr_NoMemory();
Christian Heimes44720832008-05-26 13:01:01 +0000292 goto done;
293 }
294
295 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
296 if (result != NULL) {
297 memcpy(result->ob_bytes, va.buf, va.len);
298 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
299 }
300
301 done:
302 if (va.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000303 PyBuffer_Release(&va);
Christian Heimes44720832008-05-26 13:01:01 +0000304 if (vb.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000305 PyBuffer_Release(&vb);
Christian Heimes44720832008-05-26 13:01:01 +0000306 return (PyObject *)result;
307}
308
309/* Functions stuffed into the type object */
310
311static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +0000312bytearray_length(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000313{
314 return Py_SIZE(self);
315}
316
317static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000318bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes44720832008-05-26 13:01:01 +0000319{
320 Py_ssize_t mysize;
321 Py_ssize_t size;
322 Py_buffer vo;
323
324 if (_getbuffer(other, &vo) < 0) {
325 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
326 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
327 return NULL;
328 }
329
330 mysize = Py_SIZE(self);
331 size = mysize + vo.len;
332 if (size < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000333 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000334 return PyErr_NoMemory();
335 }
336 if (size < self->ob_alloc) {
337 Py_SIZE(self) = size;
338 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
339 }
340 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000341 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000342 return NULL;
343 }
344 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000345 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000346 Py_INCREF(self);
347 return (PyObject *)self;
348}
349
350static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000351bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000352{
353 PyByteArrayObject *result;
354 Py_ssize_t mysize;
355 Py_ssize_t size;
356
357 if (count < 0)
358 count = 0;
359 mysize = Py_SIZE(self);
360 size = mysize * count;
361 if (count != 0 && size / count != mysize)
362 return PyErr_NoMemory();
363 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
364 if (result != NULL && size != 0) {
365 if (mysize == 1)
366 memset(result->ob_bytes, self->ob_bytes[0], size);
367 else {
368 Py_ssize_t i;
369 for (i = 0; i < count; i++)
370 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
371 }
372 }
373 return (PyObject *)result;
374}
375
376static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000377bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000378{
379 Py_ssize_t mysize;
380 Py_ssize_t size;
381
382 if (count < 0)
383 count = 0;
384 mysize = Py_SIZE(self);
385 size = mysize * count;
386 if (count != 0 && size / count != mysize)
387 return PyErr_NoMemory();
388 if (size < self->ob_alloc) {
389 Py_SIZE(self) = size;
390 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
391 }
392 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
393 return NULL;
394
395 if (mysize == 1)
396 memset(self->ob_bytes, self->ob_bytes[0], size);
397 else {
398 Py_ssize_t i;
399 for (i = 1; i < count; i++)
400 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
401 }
402
403 Py_INCREF(self);
404 return (PyObject *)self;
405}
406
407static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000408bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes44720832008-05-26 13:01:01 +0000409{
410 if (i < 0)
411 i += Py_SIZE(self);
412 if (i < 0 || i >= Py_SIZE(self)) {
413 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
414 return NULL;
415 }
416 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
417}
418
419static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000420bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes44720832008-05-26 13:01:01 +0000421{
Georg Brandl3e483f62008-07-16 22:57:41 +0000422 if (PyIndex_Check(index)) {
423 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000424
425 if (i == -1 && PyErr_Occurred())
426 return NULL;
427
428 if (i < 0)
429 i += PyByteArray_GET_SIZE(self);
430
431 if (i < 0 || i >= Py_SIZE(self)) {
432 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
433 return NULL;
434 }
435 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
436 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000437 else if (PySlice_Check(index)) {
Christian Heimes44720832008-05-26 13:01:01 +0000438 Py_ssize_t start, stop, step, slicelength, cur, i;
Georg Brandl3e483f62008-07-16 22:57:41 +0000439 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes44720832008-05-26 13:01:01 +0000440 PyByteArray_GET_SIZE(self),
441 &start, &stop, &step, &slicelength) < 0) {
442 return NULL;
443 }
444
445 if (slicelength <= 0)
446 return PyByteArray_FromStringAndSize("", 0);
447 else if (step == 1) {
448 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
449 slicelength);
450 }
451 else {
452 char *source_buf = PyByteArray_AS_STRING(self);
453 char *result_buf = (char *)PyMem_Malloc(slicelength);
454 PyObject *result;
455
456 if (result_buf == NULL)
457 return PyErr_NoMemory();
458
459 for (cur = start, i = 0; i < slicelength;
460 cur += step, i++) {
461 result_buf[i] = source_buf[cur];
462 }
463 result = PyByteArray_FromStringAndSize(result_buf, slicelength);
464 PyMem_Free(result_buf);
465 return result;
466 }
467 }
468 else {
469 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
470 return NULL;
471 }
472}
473
474static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000475bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes44720832008-05-26 13:01:01 +0000476 PyObject *values)
477{
478 Py_ssize_t avail, needed;
479 void *bytes;
480 Py_buffer vbytes;
481 int res = 0;
482
483 vbytes.len = -1;
484 if (values == (PyObject *)self) {
485 /* Make a copy and call this function recursively */
486 int err;
487 values = PyByteArray_FromObject(values);
488 if (values == NULL)
489 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000490 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes44720832008-05-26 13:01:01 +0000491 Py_DECREF(values);
492 return err;
493 }
494 if (values == NULL) {
495 /* del b[lo:hi] */
496 bytes = NULL;
497 needed = 0;
498 }
499 else {
500 if (_getbuffer(values, &vbytes) < 0) {
501 PyErr_Format(PyExc_TypeError,
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000502 "can't set bytearray slice from %.100s",
Christian Heimes44720832008-05-26 13:01:01 +0000503 Py_TYPE(values)->tp_name);
504 return -1;
505 }
506 needed = vbytes.len;
507 bytes = vbytes.buf;
508 }
509
510 if (lo < 0)
511 lo = 0;
512 if (hi < lo)
513 hi = lo;
514 if (hi > Py_SIZE(self))
515 hi = Py_SIZE(self);
516
517 avail = hi - lo;
518 if (avail < 0)
519 lo = hi = avail = 0;
520
521 if (avail != needed) {
522 if (avail > needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000523 if (!_canresize(self)) {
524 res = -1;
525 goto finish;
526 }
Christian Heimes44720832008-05-26 13:01:01 +0000527 /*
528 0 lo hi old_size
529 | |<----avail----->|<-----tomove------>|
530 | |<-needed->|<-----tomove------>|
531 0 lo new_hi new_size
532 */
533 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
534 Py_SIZE(self) - hi);
535 }
536 /* XXX(nnorwitz): need to verify this can't overflow! */
537 if (PyByteArray_Resize((PyObject *)self,
538 Py_SIZE(self) + needed - avail) < 0) {
539 res = -1;
540 goto finish;
541 }
542 if (avail < needed) {
543 /*
544 0 lo hi old_size
545 | |<-avail->|<-----tomove------>|
546 | |<----needed---->|<-----tomove------>|
547 0 lo new_hi new_size
548 */
549 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
550 Py_SIZE(self) - lo - needed);
551 }
552 }
553
554 if (needed > 0)
555 memcpy(self->ob_bytes + lo, bytes, needed);
556
557
558 finish:
559 if (vbytes.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000560 PyBuffer_Release(&vbytes);
Christian Heimes44720832008-05-26 13:01:01 +0000561 return res;
562}
563
564static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000565bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes44720832008-05-26 13:01:01 +0000566{
567 int ival;
568
569 if (i < 0)
570 i += Py_SIZE(self);
571
572 if (i < 0 || i >= Py_SIZE(self)) {
573 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
574 return -1;
575 }
576
577 if (value == NULL)
Benjamin Petersond6720012009-04-18 15:31:34 +0000578 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes44720832008-05-26 13:01:01 +0000579
580 if (!_getbytevalue(value, &ival))
581 return -1;
582
583 self->ob_bytes[i] = ival;
584 return 0;
585}
586
587static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000588bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes44720832008-05-26 13:01:01 +0000589{
590 Py_ssize_t start, stop, step, slicelen, needed;
591 char *bytes;
592
Georg Brandl3e483f62008-07-16 22:57:41 +0000593 if (PyIndex_Check(index)) {
594 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000595
596 if (i == -1 && PyErr_Occurred())
597 return -1;
598
599 if (i < 0)
600 i += PyByteArray_GET_SIZE(self);
601
602 if (i < 0 || i >= Py_SIZE(self)) {
603 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
604 return -1;
605 }
606
607 if (values == NULL) {
608 /* Fall through to slice assignment */
609 start = i;
610 stop = i + 1;
611 step = 1;
612 slicelen = 1;
613 }
614 else {
Georg Brandl3e483f62008-07-16 22:57:41 +0000615 int ival;
616 if (!_getbytevalue(values, &ival))
Christian Heimes44720832008-05-26 13:01:01 +0000617 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000618 self->ob_bytes[i] = (char)ival;
619 return 0;
620 }
621 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000622 else if (PySlice_Check(index)) {
623 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes44720832008-05-26 13:01:01 +0000624 PyByteArray_GET_SIZE(self),
625 &start, &stop, &step, &slicelen) < 0) {
626 return -1;
627 }
628 }
629 else {
630 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
631 return -1;
632 }
633
634 if (values == NULL) {
635 bytes = NULL;
636 needed = 0;
637 }
638 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
639 /* Make a copy an call this function recursively */
640 int err;
641 values = PyByteArray_FromObject(values);
642 if (values == NULL)
643 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000644 err = bytearray_ass_subscript(self, index, values);
Christian Heimes44720832008-05-26 13:01:01 +0000645 Py_DECREF(values);
646 return err;
647 }
648 else {
649 assert(PyByteArray_Check(values));
650 bytes = ((PyByteArrayObject *)values)->ob_bytes;
651 needed = Py_SIZE(values);
652 }
653 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
654 if ((step < 0 && start < stop) ||
655 (step > 0 && start > stop))
656 stop = start;
657 if (step == 1) {
658 if (slicelen != needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000659 if (!_canresize(self))
660 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000661 if (slicelen > needed) {
662 /*
663 0 start stop old_size
664 | |<---slicelen--->|<-----tomove------>|
665 | |<-needed->|<-----tomove------>|
666 0 lo new_hi new_size
667 */
668 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
669 Py_SIZE(self) - stop);
670 }
671 if (PyByteArray_Resize((PyObject *)self,
672 Py_SIZE(self) + needed - slicelen) < 0)
673 return -1;
674 if (slicelen < needed) {
675 /*
676 0 lo hi old_size
677 | |<-avail->|<-----tomove------>|
678 | |<----needed---->|<-----tomove------>|
679 0 lo new_hi new_size
680 */
681 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
682 Py_SIZE(self) - start - needed);
683 }
684 }
685
686 if (needed > 0)
687 memcpy(self->ob_bytes + start, bytes, needed);
688
689 return 0;
690 }
691 else {
692 if (needed == 0) {
693 /* Delete slice */
694 Py_ssize_t cur, i;
695
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000696 if (!_canresize(self))
697 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000698 if (step < 0) {
699 stop = start + 1;
700 start = stop + step * (slicelen - 1) - 1;
701 step = -step;
702 }
703 for (cur = start, i = 0;
704 i < slicelen; cur += step, i++) {
705 Py_ssize_t lim = step - 1;
706
707 if (cur + step >= PyByteArray_GET_SIZE(self))
708 lim = PyByteArray_GET_SIZE(self) - cur - 1;
709
710 memmove(self->ob_bytes + cur - i,
711 self->ob_bytes + cur + 1, lim);
712 }
713 /* Move the tail of the bytes, in one chunk */
714 cur = start + slicelen*step;
715 if (cur < PyByteArray_GET_SIZE(self)) {
716 memmove(self->ob_bytes + cur - slicelen,
717 self->ob_bytes + cur,
718 PyByteArray_GET_SIZE(self) - cur);
719 }
720 if (PyByteArray_Resize((PyObject *)self,
721 PyByteArray_GET_SIZE(self) - slicelen) < 0)
722 return -1;
723
724 return 0;
725 }
726 else {
727 /* Assign slice */
728 Py_ssize_t cur, i;
729
730 if (needed != slicelen) {
731 PyErr_Format(PyExc_ValueError,
732 "attempt to assign bytes of size %zd "
733 "to extended slice of size %zd",
734 needed, slicelen);
735 return -1;
736 }
737 for (cur = start, i = 0; i < slicelen; cur += step, i++)
738 self->ob_bytes[cur] = bytes[i];
739 return 0;
740 }
741 }
742}
743
744static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000745bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes44720832008-05-26 13:01:01 +0000746{
747 static char *kwlist[] = {"source", "encoding", "errors", 0};
748 PyObject *arg = NULL;
749 const char *encoding = NULL;
750 const char *errors = NULL;
751 Py_ssize_t count;
752 PyObject *it;
753 PyObject *(*iternext)(PyObject *);
754
755 if (Py_SIZE(self) != 0) {
756 /* Empty previous contents (yes, do this first of all!) */
757 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
758 return -1;
759 }
760
761 /* Parse arguments */
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000762 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes44720832008-05-26 13:01:01 +0000763 &arg, &encoding, &errors))
764 return -1;
765
766 /* Make a quick exit if no first argument */
767 if (arg == NULL) {
768 if (encoding != NULL || errors != NULL) {
769 PyErr_SetString(PyExc_TypeError,
770 "encoding or errors without sequence argument");
771 return -1;
772 }
773 return 0;
774 }
775
776 if (PyBytes_Check(arg)) {
777 PyObject *new, *encoded;
778 if (encoding != NULL) {
779 encoded = PyCodec_Encode(arg, encoding, errors);
780 if (encoded == NULL)
781 return -1;
782 assert(PyBytes_Check(encoded));
783 }
784 else {
785 encoded = arg;
786 Py_INCREF(arg);
787 }
Benjamin Petersond6720012009-04-18 15:31:34 +0000788 new = bytearray_iconcat(self, arg);
Christian Heimes44720832008-05-26 13:01:01 +0000789 Py_DECREF(encoded);
790 if (new == NULL)
791 return -1;
792 Py_DECREF(new);
793 return 0;
794 }
795
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000796#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +0000797 if (PyUnicode_Check(arg)) {
798 /* Encode via the codec registry */
799 PyObject *encoded, *new;
800 if (encoding == NULL) {
801 PyErr_SetString(PyExc_TypeError,
802 "unicode argument without an encoding");
803 return -1;
804 }
805 encoded = PyCodec_Encode(arg, encoding, errors);
806 if (encoded == NULL)
807 return -1;
808 assert(PyBytes_Check(encoded));
Benjamin Petersond6720012009-04-18 15:31:34 +0000809 new = bytearray_iconcat(self, encoded);
Christian Heimes44720832008-05-26 13:01:01 +0000810 Py_DECREF(encoded);
811 if (new == NULL)
812 return -1;
813 Py_DECREF(new);
814 return 0;
815 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000816#endif
Christian Heimes44720832008-05-26 13:01:01 +0000817
818 /* If it's not unicode, there can't be encoding or errors */
819 if (encoding != NULL || errors != NULL) {
820 PyErr_SetString(PyExc_TypeError,
821 "encoding or errors without a string argument");
822 return -1;
823 }
824
825 /* Is it an int? */
826 count = PyNumber_AsSsize_t(arg, PyExc_ValueError);
827 if (count == -1 && PyErr_Occurred())
828 PyErr_Clear();
829 else {
830 if (count < 0) {
831 PyErr_SetString(PyExc_ValueError, "negative count");
832 return -1;
833 }
834 if (count > 0) {
835 if (PyByteArray_Resize((PyObject *)self, count))
836 return -1;
837 memset(self->ob_bytes, 0, count);
838 }
839 return 0;
840 }
841
842 /* Use the buffer API */
843 if (PyObject_CheckBuffer(arg)) {
844 Py_ssize_t size;
845 Py_buffer view;
846 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
847 return -1;
848 size = view.len;
849 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
850 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
851 goto fail;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000852 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000853 return 0;
854 fail:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000855 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000856 return -1;
857 }
858
859 /* XXX Optimize this if the arguments is a list, tuple */
860
861 /* Get the iterator */
862 it = PyObject_GetIter(arg);
863 if (it == NULL)
864 return -1;
865 iternext = *Py_TYPE(it)->tp_iternext;
866
867 /* Run the iterator to exhaustion */
868 for (;;) {
869 PyObject *item;
Georg Brandl3e758462008-07-16 23:10:05 +0000870 int rc, value;
Christian Heimes44720832008-05-26 13:01:01 +0000871
872 /* Get the next item */
873 item = iternext(it);
874 if (item == NULL) {
875 if (PyErr_Occurred()) {
876 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
877 goto error;
878 PyErr_Clear();
879 }
880 break;
881 }
882
883 /* Interpret it as an int (__index__) */
Georg Brandl3e758462008-07-16 23:10:05 +0000884 rc = _getbytevalue(item, &value);
Christian Heimes44720832008-05-26 13:01:01 +0000885 Py_DECREF(item);
Georg Brandl3e758462008-07-16 23:10:05 +0000886 if (!rc)
Christian Heimes44720832008-05-26 13:01:01 +0000887 goto error;
888
Christian Heimes44720832008-05-26 13:01:01 +0000889 /* Append the byte */
890 if (Py_SIZE(self) < self->ob_alloc)
891 Py_SIZE(self)++;
892 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
893 goto error;
894 self->ob_bytes[Py_SIZE(self)-1] = value;
895 }
896
897 /* Clean up and return success */
898 Py_DECREF(it);
899 return 0;
900
901 error:
902 /* Error handling when it != NULL */
903 Py_DECREF(it);
904 return -1;
905}
906
907/* Mostly copied from string_repr, but without the
908 "smart quote" functionality. */
909static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000910bytearray_repr(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000911{
912 static const char *hexdigits = "0123456789abcdef";
913 const char *quote_prefix = "bytearray(b";
914 const char *quote_postfix = ")";
915 Py_ssize_t length = Py_SIZE(self);
916 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
917 size_t newsize = 14 + 4 * length;
918 PyObject *v;
919 if (newsize > PY_SSIZE_T_MAX || newsize / 4 - 3 != length) {
920 PyErr_SetString(PyExc_OverflowError,
921 "bytearray object is too large to make repr");
922 return NULL;
923 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000924 v = PyString_FromStringAndSize(NULL, newsize);
Christian Heimes44720832008-05-26 13:01:01 +0000925 if (v == NULL) {
926 return NULL;
927 }
928 else {
929 register Py_ssize_t i;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000930 register char c;
931 register char *p;
Christian Heimes44720832008-05-26 13:01:01 +0000932 int quote;
933
934 /* Figure out which quote to use; single is preferred */
935 quote = '\'';
936 {
937 char *test, *start;
938 start = PyByteArray_AS_STRING(self);
939 for (test = start; test < start+length; ++test) {
940 if (*test == '"') {
941 quote = '\''; /* back to single */
942 goto decided;
943 }
944 else if (*test == '\'')
945 quote = '"';
946 }
947 decided:
948 ;
949 }
950
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000951 p = PyString_AS_STRING(v);
Christian Heimes44720832008-05-26 13:01:01 +0000952 while (*quote_prefix)
953 *p++ = *quote_prefix++;
954 *p++ = quote;
955
956 for (i = 0; i < length; i++) {
957 /* There's at least enough room for a hex escape
958 and a closing quote. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000959 assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
Christian Heimes44720832008-05-26 13:01:01 +0000960 c = self->ob_bytes[i];
961 if (c == '\'' || c == '\\')
962 *p++ = '\\', *p++ = c;
963 else if (c == '\t')
964 *p++ = '\\', *p++ = 't';
965 else if (c == '\n')
966 *p++ = '\\', *p++ = 'n';
967 else if (c == '\r')
968 *p++ = '\\', *p++ = 'r';
969 else if (c == 0)
970 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
971 else if (c < ' ' || c >= 0x7f) {
972 *p++ = '\\';
973 *p++ = 'x';
974 *p++ = hexdigits[(c & 0xf0) >> 4];
975 *p++ = hexdigits[c & 0xf];
976 }
977 else
978 *p++ = c;
979 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000980 assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
Christian Heimes44720832008-05-26 13:01:01 +0000981 *p++ = quote;
982 while (*quote_postfix) {
983 *p++ = *quote_postfix++;
984 }
985 *p = '\0';
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000986 if (_PyString_Resize(&v, (p - PyString_AS_STRING(v)))) {
Christian Heimes44720832008-05-26 13:01:01 +0000987 Py_DECREF(v);
988 return NULL;
989 }
990 return v;
991 }
992}
993
994static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000995bytearray_str(PyObject *op)
Christian Heimes44720832008-05-26 13:01:01 +0000996{
997#if 0
998 if (Py_BytesWarningFlag) {
999 if (PyErr_WarnEx(PyExc_BytesWarning,
1000 "str() on a bytearray instance", 1))
1001 return NULL;
1002 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001003 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes44720832008-05-26 13:01:01 +00001004#endif
1005 return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
1006}
1007
1008static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001009bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes44720832008-05-26 13:01:01 +00001010{
1011 Py_ssize_t self_size, other_size;
1012 Py_buffer self_bytes, other_bytes;
1013 PyObject *res;
1014 Py_ssize_t minsize;
1015 int cmp;
1016
1017 /* Bytes can be compared to anything that supports the (binary)
1018 buffer API. Except that a comparison with Unicode is always an
1019 error, even if the comparison is for equality. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001020#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00001021 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1022 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
1023 if (Py_BytesWarningFlag && op == Py_EQ) {
1024 if (PyErr_WarnEx(PyExc_BytesWarning,
Ezio Melottid2342082010-01-14 11:34:10 +00001025 "Comparison between bytearray and string", 1))
Christian Heimes44720832008-05-26 13:01:01 +00001026 return NULL;
1027 }
1028
1029 Py_INCREF(Py_NotImplemented);
1030 return Py_NotImplemented;
1031 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001032#endif
Christian Heimes44720832008-05-26 13:01:01 +00001033
1034 self_size = _getbuffer(self, &self_bytes);
1035 if (self_size < 0) {
1036 PyErr_Clear();
1037 Py_INCREF(Py_NotImplemented);
1038 return Py_NotImplemented;
1039 }
1040
1041 other_size = _getbuffer(other, &other_bytes);
1042 if (other_size < 0) {
1043 PyErr_Clear();
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001044 PyBuffer_Release(&self_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001045 Py_INCREF(Py_NotImplemented);
1046 return Py_NotImplemented;
1047 }
1048
1049 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1050 /* Shortcut: if the lengths differ, the objects differ */
1051 cmp = (op == Py_NE);
1052 }
1053 else {
1054 minsize = self_size;
1055 if (other_size < minsize)
1056 minsize = other_size;
1057
1058 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1059 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1060
1061 if (cmp == 0) {
1062 if (self_size < other_size)
1063 cmp = -1;
1064 else if (self_size > other_size)
1065 cmp = 1;
1066 }
1067
1068 switch (op) {
1069 case Py_LT: cmp = cmp < 0; break;
1070 case Py_LE: cmp = cmp <= 0; break;
1071 case Py_EQ: cmp = cmp == 0; break;
1072 case Py_NE: cmp = cmp != 0; break;
1073 case Py_GT: cmp = cmp > 0; break;
1074 case Py_GE: cmp = cmp >= 0; break;
1075 }
1076 }
1077
1078 res = cmp ? Py_True : Py_False;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001079 PyBuffer_Release(&self_bytes);
1080 PyBuffer_Release(&other_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001081 Py_INCREF(res);
1082 return res;
1083}
1084
1085static void
Benjamin Petersond6720012009-04-18 15:31:34 +00001086bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00001087{
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001088 if (self->ob_exports > 0) {
1089 PyErr_SetString(PyExc_SystemError,
Georg Brandl517cfdc2009-04-05 13:16:35 +00001090 "deallocated bytearray object has exported buffers");
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001091 PyErr_Print();
1092 }
Christian Heimes44720832008-05-26 13:01:01 +00001093 if (self->ob_bytes != 0) {
1094 PyMem_Free(self->ob_bytes);
1095 }
1096 Py_TYPE(self)->tp_free((PyObject *)self);
1097}
1098
1099
1100/* -------------------------------------------------------------------- */
1101/* Methods */
1102
1103#define STRINGLIB_CHAR char
Christian Heimes44720832008-05-26 13:01:01 +00001104#define STRINGLIB_LEN PyByteArray_GET_SIZE
1105#define STRINGLIB_STR PyByteArray_AS_STRING
1106#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrou64672132010-01-13 07:55:48 +00001107#define STRINGLIB_ISSPACE Py_ISSPACE
1108#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes44720832008-05-26 13:01:01 +00001109#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1110#define STRINGLIB_MUTABLE 1
1111
1112#include "stringlib/fastsearch.h"
1113#include "stringlib/count.h"
1114#include "stringlib/find.h"
1115#include "stringlib/partition.h"
Antoine Pitrou64672132010-01-13 07:55:48 +00001116#include "stringlib/split.h"
Christian Heimes44720832008-05-26 13:01:01 +00001117#include "stringlib/ctype.h"
1118#include "stringlib/transmogrify.h"
1119
1120
1121/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1122were copied from the old char* style string object. */
1123
Antoine Pitrou64672132010-01-13 07:55:48 +00001124/* helper macro to fixup start/end slice values */
1125#define ADJUST_INDICES(start, end, len) \
1126 if (end > len) \
1127 end = len; \
1128 else if (end < 0) { \
1129 end += len; \
1130 if (end < 0) \
1131 end = 0; \
1132 } \
1133 if (start < 0) { \
1134 start += len; \
1135 if (start < 0) \
1136 start = 0; \
1137 }
Christian Heimes44720832008-05-26 13:01:01 +00001138
1139Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Petersond6720012009-04-18 15:31:34 +00001140bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes44720832008-05-26 13:01:01 +00001141{
1142 PyObject *subobj;
1143 Py_buffer subbuf;
1144 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1145 Py_ssize_t res;
1146
1147 if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
1148 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1149 return -2;
1150 if (_getbuffer(subobj, &subbuf) < 0)
1151 return -2;
1152 if (dir > 0)
1153 res = stringlib_find_slice(
1154 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1155 subbuf.buf, subbuf.len, start, end);
1156 else
1157 res = stringlib_rfind_slice(
1158 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1159 subbuf.buf, subbuf.len, start, end);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001160 PyBuffer_Release(&subbuf);
Christian Heimes44720832008-05-26 13:01:01 +00001161 return res;
1162}
1163
1164PyDoc_STRVAR(find__doc__,
1165"B.find(sub [,start [,end]]) -> int\n\
1166\n\
1167Return the lowest index in B where subsection sub is found,\n\
1168such that sub is contained within s[start,end]. Optional\n\
1169arguments start and end are interpreted as in slice notation.\n\
1170\n\
1171Return -1 on failure.");
1172
1173static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001174bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001175{
Benjamin Petersond6720012009-04-18 15:31:34 +00001176 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001177 if (result == -2)
1178 return NULL;
1179 return PyInt_FromSsize_t(result);
1180}
1181
1182PyDoc_STRVAR(count__doc__,
1183"B.count(sub [,start [,end]]) -> int\n\
1184\n\
1185Return the number of non-overlapping occurrences of subsection sub in\n\
1186bytes B[start:end]. Optional arguments start and end are interpreted\n\
1187as in slice notation.");
1188
1189static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001190bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001191{
1192 PyObject *sub_obj;
1193 const char *str = PyByteArray_AS_STRING(self);
1194 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1195 Py_buffer vsub;
1196 PyObject *count_obj;
1197
1198 if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1199 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1200 return NULL;
1201
1202 if (_getbuffer(sub_obj, &vsub) < 0)
1203 return NULL;
1204
Antoine Pitrou64672132010-01-13 07:55:48 +00001205 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes44720832008-05-26 13:01:01 +00001206
1207 count_obj = PyInt_FromSsize_t(
Antoine Pitrou64672132010-01-13 07:55:48 +00001208 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes44720832008-05-26 13:01:01 +00001209 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001210 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00001211 return count_obj;
1212}
1213
1214
1215PyDoc_STRVAR(index__doc__,
1216"B.index(sub [,start [,end]]) -> int\n\
1217\n\
1218Like B.find() but raise ValueError when the subsection is not found.");
1219
1220static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001221bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001222{
Benjamin Petersond6720012009-04-18 15:31:34 +00001223 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001224 if (result == -2)
1225 return NULL;
1226 if (result == -1) {
1227 PyErr_SetString(PyExc_ValueError,
1228 "subsection not found");
1229 return NULL;
1230 }
1231 return PyInt_FromSsize_t(result);
1232}
1233
1234
1235PyDoc_STRVAR(rfind__doc__,
1236"B.rfind(sub [,start [,end]]) -> int\n\
1237\n\
1238Return the highest index in B where subsection sub is found,\n\
1239such that sub is contained within s[start,end]. Optional\n\
1240arguments start and end are interpreted as in slice notation.\n\
1241\n\
1242Return -1 on failure.");
1243
1244static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001245bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001246{
Benjamin Petersond6720012009-04-18 15:31:34 +00001247 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001248 if (result == -2)
1249 return NULL;
1250 return PyInt_FromSsize_t(result);
1251}
1252
1253
1254PyDoc_STRVAR(rindex__doc__,
1255"B.rindex(sub [,start [,end]]) -> int\n\
1256\n\
1257Like B.rfind() but raise ValueError when the subsection is not found.");
1258
1259static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001260bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001261{
Benjamin Petersond6720012009-04-18 15:31:34 +00001262 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001263 if (result == -2)
1264 return NULL;
1265 if (result == -1) {
1266 PyErr_SetString(PyExc_ValueError,
1267 "subsection not found");
1268 return NULL;
1269 }
1270 return PyInt_FromSsize_t(result);
1271}
1272
1273
1274static int
Benjamin Petersond6720012009-04-18 15:31:34 +00001275bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00001276{
1277 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1278 if (ival == -1 && PyErr_Occurred()) {
1279 Py_buffer varg;
1280 int pos;
1281 PyErr_Clear();
1282 if (_getbuffer(arg, &varg) < 0)
1283 return -1;
1284 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1285 varg.buf, varg.len, 0);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001286 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00001287 return pos >= 0;
1288 }
1289 if (ival < 0 || ival >= 256) {
1290 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1291 return -1;
1292 }
1293
1294 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1295}
1296
1297
1298/* Matches the end (direction >= 0) or start (direction < 0) of self
1299 * against substr, using the start and end arguments. Returns
1300 * -1 on error, 0 if not found and 1 if found.
1301 */
1302Py_LOCAL(int)
Benjamin Petersond6720012009-04-18 15:31:34 +00001303_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes44720832008-05-26 13:01:01 +00001304 Py_ssize_t end, int direction)
1305{
1306 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1307 const char* str;
1308 Py_buffer vsubstr;
1309 int rv = 0;
1310
1311 str = PyByteArray_AS_STRING(self);
1312
1313 if (_getbuffer(substr, &vsubstr) < 0)
1314 return -1;
1315
Antoine Pitrou64672132010-01-13 07:55:48 +00001316 ADJUST_INDICES(start, end, len);
Christian Heimes44720832008-05-26 13:01:01 +00001317
1318 if (direction < 0) {
1319 /* startswith */
1320 if (start+vsubstr.len > len) {
1321 goto done;
1322 }
1323 } else {
1324 /* endswith */
1325 if (end-start < vsubstr.len || start > len) {
1326 goto done;
1327 }
1328
1329 if (end-vsubstr.len > start)
1330 start = end - vsubstr.len;
1331 }
1332 if (end-start >= vsubstr.len)
1333 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1334
1335done:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001336 PyBuffer_Release(&vsubstr);
Christian Heimes44720832008-05-26 13:01:01 +00001337 return rv;
1338}
1339
1340
1341PyDoc_STRVAR(startswith__doc__,
1342"B.startswith(prefix [,start [,end]]) -> bool\n\
1343\n\
1344Return True if B starts with the specified prefix, False otherwise.\n\
1345With optional start, test B beginning at that position.\n\
1346With optional end, stop comparing B at that position.\n\
1347prefix can also be a tuple of strings to try.");
1348
1349static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001350bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001351{
1352 Py_ssize_t start = 0;
1353 Py_ssize_t end = PY_SSIZE_T_MAX;
1354 PyObject *subobj;
1355 int result;
1356
1357 if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
1358 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1359 return NULL;
1360 if (PyTuple_Check(subobj)) {
1361 Py_ssize_t i;
1362 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001363 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001364 PyTuple_GET_ITEM(subobj, i),
1365 start, end, -1);
1366 if (result == -1)
1367 return NULL;
1368 else if (result) {
1369 Py_RETURN_TRUE;
1370 }
1371 }
1372 Py_RETURN_FALSE;
1373 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001374 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001375 if (result == -1)
1376 return NULL;
1377 else
1378 return PyBool_FromLong(result);
1379}
1380
1381PyDoc_STRVAR(endswith__doc__,
1382"B.endswith(suffix [,start [,end]]) -> bool\n\
1383\n\
1384Return True if B ends with the specified suffix, False otherwise.\n\
1385With optional start, test B beginning at that position.\n\
1386With optional end, stop comparing B at that position.\n\
1387suffix can also be a tuple of strings to try.");
1388
1389static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001390bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001391{
1392 Py_ssize_t start = 0;
1393 Py_ssize_t end = PY_SSIZE_T_MAX;
1394 PyObject *subobj;
1395 int result;
1396
1397 if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
1398 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1399 return NULL;
1400 if (PyTuple_Check(subobj)) {
1401 Py_ssize_t i;
1402 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001403 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001404 PyTuple_GET_ITEM(subobj, i),
1405 start, end, +1);
1406 if (result == -1)
1407 return NULL;
1408 else if (result) {
1409 Py_RETURN_TRUE;
1410 }
1411 }
1412 Py_RETURN_FALSE;
1413 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001414 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001415 if (result == -1)
1416 return NULL;
1417 else
1418 return PyBool_FromLong(result);
1419}
1420
1421
1422PyDoc_STRVAR(translate__doc__,
1423"B.translate(table[, deletechars]) -> bytearray\n\
1424\n\
1425Return a copy of B, where all characters occurring in the\n\
1426optional argument deletechars are removed, and the remaining\n\
1427characters have been mapped through the given translation\n\
1428table, which must be a bytes object of length 256.");
1429
1430static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001431bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001432{
1433 register char *input, *output;
1434 register const char *table;
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001435 register Py_ssize_t i, c;
Christian Heimes44720832008-05-26 13:01:01 +00001436 PyObject *input_obj = (PyObject*)self;
1437 const char *output_start;
1438 Py_ssize_t inlen;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001439 PyObject *result = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001440 int trans_table[256];
Georg Brandl6425a2f2008-12-28 11:54:53 +00001441 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001442 Py_buffer vtable, vdel;
1443
1444 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1445 &tableobj, &delobj))
1446 return NULL;
1447
Georg Brandl6425a2f2008-12-28 11:54:53 +00001448 if (tableobj == Py_None) {
1449 table = NULL;
1450 tableobj = NULL;
1451 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00001452 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001453 } else {
1454 if (vtable.len != 256) {
1455 PyErr_SetString(PyExc_ValueError,
1456 "translation table must be 256 characters long");
Georg Brandlec812ca2009-07-22 11:57:15 +00001457 PyBuffer_Release(&vtable);
1458 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001459 }
1460 table = (const char*)vtable.buf;
Christian Heimes44720832008-05-26 13:01:01 +00001461 }
1462
1463 if (delobj != NULL) {
1464 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandlec812ca2009-07-22 11:57:15 +00001465 if (tableobj != NULL)
1466 PyBuffer_Release(&vtable);
1467 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001468 }
1469 }
1470 else {
1471 vdel.buf = NULL;
1472 vdel.len = 0;
1473 }
1474
Christian Heimes44720832008-05-26 13:01:01 +00001475 inlen = PyByteArray_GET_SIZE(input_obj);
1476 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1477 if (result == NULL)
1478 goto done;
1479 output_start = output = PyByteArray_AsString(result);
1480 input = PyByteArray_AS_STRING(input_obj);
1481
Georg Brandl6425a2f2008-12-28 11:54:53 +00001482 if (vdel.len == 0 && table != NULL) {
Christian Heimes44720832008-05-26 13:01:01 +00001483 /* If no deletions are required, use faster code */
1484 for (i = inlen; --i >= 0; ) {
1485 c = Py_CHARMASK(*input++);
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001486 *output++ = table[c];
Christian Heimes44720832008-05-26 13:01:01 +00001487 }
Christian Heimes44720832008-05-26 13:01:01 +00001488 goto done;
1489 }
Georg Brandl6425a2f2008-12-28 11:54:53 +00001490
1491 if (table == NULL) {
1492 for (i = 0; i < 256; i++)
1493 trans_table[i] = Py_CHARMASK(i);
1494 } else {
1495 for (i = 0; i < 256; i++)
1496 trans_table[i] = Py_CHARMASK(table[i]);
1497 }
Christian Heimes44720832008-05-26 13:01:01 +00001498
1499 for (i = 0; i < vdel.len; i++)
1500 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1501
1502 for (i = inlen; --i >= 0; ) {
1503 c = Py_CHARMASK(*input++);
1504 if (trans_table[c] != -1)
1505 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1506 continue;
Christian Heimes44720832008-05-26 13:01:01 +00001507 }
1508 /* Fix the size of the resulting string */
1509 if (inlen > 0)
1510 PyByteArray_Resize(result, output - output_start);
1511
1512done:
Georg Brandl6425a2f2008-12-28 11:54:53 +00001513 if (tableobj != NULL)
1514 PyBuffer_Release(&vtable);
Christian Heimes44720832008-05-26 13:01:01 +00001515 if (delobj != NULL)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001516 PyBuffer_Release(&vdel);
Christian Heimes44720832008-05-26 13:01:01 +00001517 return result;
1518}
1519
1520
Christian Heimes44720832008-05-26 13:01:01 +00001521/* find and count characters and substrings */
1522
1523#define findchar(target, target_len, c) \
1524 ((char *)memchr((const void *)(target), c, target_len))
1525
Christian Heimes44720832008-05-26 13:01:01 +00001526
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001527/* Bytes ops must return a string, create a copy */
Christian Heimes44720832008-05-26 13:01:01 +00001528Py_LOCAL(PyByteArrayObject *)
1529return_self(PyByteArrayObject *self)
1530{
Christian Heimes44720832008-05-26 13:01:01 +00001531 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1532 PyByteArray_AS_STRING(self),
1533 PyByteArray_GET_SIZE(self));
1534}
1535
1536Py_LOCAL_INLINE(Py_ssize_t)
1537countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1538{
1539 Py_ssize_t count=0;
1540 const char *start=target;
1541 const char *end=target+target_len;
1542
1543 while ( (start=findchar(start, end-start, c)) != NULL ) {
1544 count++;
1545 if (count >= maxcount)
1546 break;
1547 start += 1;
1548 }
1549 return count;
1550}
1551
Christian Heimes44720832008-05-26 13:01:01 +00001552
1553/* Algorithms for different cases of string replacement */
1554
1555/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1556Py_LOCAL(PyByteArrayObject *)
1557replace_interleave(PyByteArrayObject *self,
1558 const char *to_s, Py_ssize_t to_len,
1559 Py_ssize_t maxcount)
1560{
1561 char *self_s, *result_s;
1562 Py_ssize_t self_len, result_len;
1563 Py_ssize_t count, i, product;
1564 PyByteArrayObject *result;
1565
1566 self_len = PyByteArray_GET_SIZE(self);
1567
1568 /* 1 at the end plus 1 after every character */
1569 count = self_len+1;
1570 if (maxcount < count)
1571 count = maxcount;
1572
1573 /* Check for overflow */
1574 /* result_len = count * to_len + self_len; */
1575 product = count * to_len;
1576 if (product / to_len != count) {
1577 PyErr_SetString(PyExc_OverflowError,
1578 "replace string is too long");
1579 return NULL;
1580 }
1581 result_len = product + self_len;
1582 if (result_len < 0) {
1583 PyErr_SetString(PyExc_OverflowError,
1584 "replace string is too long");
1585 return NULL;
1586 }
1587
1588 if (! (result = (PyByteArrayObject *)
1589 PyByteArray_FromStringAndSize(NULL, result_len)) )
1590 return NULL;
1591
1592 self_s = PyByteArray_AS_STRING(self);
1593 result_s = PyByteArray_AS_STRING(result);
1594
1595 /* TODO: special case single character, which doesn't need memcpy */
1596
1597 /* Lay the first one down (guaranteed this will occur) */
1598 Py_MEMCPY(result_s, to_s, to_len);
1599 result_s += to_len;
1600 count -= 1;
1601
1602 for (i=0; i<count; i++) {
1603 *result_s++ = *self_s++;
1604 Py_MEMCPY(result_s, to_s, to_len);
1605 result_s += to_len;
1606 }
1607
1608 /* Copy the rest of the original string */
1609 Py_MEMCPY(result_s, self_s, self_len-i);
1610
1611 return result;
1612}
1613
1614/* Special case for deleting a single character */
1615/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1616Py_LOCAL(PyByteArrayObject *)
1617replace_delete_single_character(PyByteArrayObject *self,
1618 char from_c, Py_ssize_t maxcount)
1619{
1620 char *self_s, *result_s;
1621 char *start, *next, *end;
1622 Py_ssize_t self_len, result_len;
1623 Py_ssize_t count;
1624 PyByteArrayObject *result;
1625
1626 self_len = PyByteArray_GET_SIZE(self);
1627 self_s = PyByteArray_AS_STRING(self);
1628
1629 count = countchar(self_s, self_len, from_c, maxcount);
1630 if (count == 0) {
1631 return return_self(self);
1632 }
1633
1634 result_len = self_len - count; /* from_len == 1 */
1635 assert(result_len>=0);
1636
1637 if ( (result = (PyByteArrayObject *)
1638 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1639 return NULL;
1640 result_s = PyByteArray_AS_STRING(result);
1641
1642 start = self_s;
1643 end = self_s + self_len;
1644 while (count-- > 0) {
1645 next = findchar(start, end-start, from_c);
1646 if (next == NULL)
1647 break;
1648 Py_MEMCPY(result_s, start, next-start);
1649 result_s += (next-start);
1650 start = next+1;
1651 }
1652 Py_MEMCPY(result_s, start, end-start);
1653
1654 return result;
1655}
1656
1657/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1658
1659Py_LOCAL(PyByteArrayObject *)
1660replace_delete_substring(PyByteArrayObject *self,
1661 const char *from_s, Py_ssize_t from_len,
1662 Py_ssize_t maxcount)
1663{
1664 char *self_s, *result_s;
1665 char *start, *next, *end;
1666 Py_ssize_t self_len, result_len;
1667 Py_ssize_t count, offset;
1668 PyByteArrayObject *result;
1669
1670 self_len = PyByteArray_GET_SIZE(self);
1671 self_s = PyByteArray_AS_STRING(self);
1672
Antoine Pitrou64672132010-01-13 07:55:48 +00001673 count = stringlib_count(self_s, self_len,
1674 from_s, from_len,
1675 maxcount);
Christian Heimes44720832008-05-26 13:01:01 +00001676
1677 if (count == 0) {
1678 /* no matches */
1679 return return_self(self);
1680 }
1681
1682 result_len = self_len - (count * from_len);
1683 assert (result_len>=0);
1684
1685 if ( (result = (PyByteArrayObject *)
1686 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1687 return NULL;
1688
1689 result_s = PyByteArray_AS_STRING(result);
1690
1691 start = self_s;
1692 end = self_s + self_len;
1693 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001694 offset = stringlib_find(start, end-start,
1695 from_s, from_len,
1696 0);
Christian Heimes44720832008-05-26 13:01:01 +00001697 if (offset == -1)
1698 break;
1699 next = start + offset;
1700
1701 Py_MEMCPY(result_s, start, next-start);
1702
1703 result_s += (next-start);
1704 start = next+from_len;
1705 }
1706 Py_MEMCPY(result_s, start, end-start);
1707 return result;
1708}
1709
1710/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1711Py_LOCAL(PyByteArrayObject *)
1712replace_single_character_in_place(PyByteArrayObject *self,
1713 char from_c, char to_c,
1714 Py_ssize_t maxcount)
1715{
1716 char *self_s, *result_s, *start, *end, *next;
1717 Py_ssize_t self_len;
1718 PyByteArrayObject *result;
1719
1720 /* The result string will be the same size */
1721 self_s = PyByteArray_AS_STRING(self);
1722 self_len = PyByteArray_GET_SIZE(self);
1723
1724 next = findchar(self_s, self_len, from_c);
1725
1726 if (next == NULL) {
1727 /* No matches; return the original bytes */
1728 return return_self(self);
1729 }
1730
1731 /* Need to make a new bytes */
1732 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1733 if (result == NULL)
1734 return NULL;
1735 result_s = PyByteArray_AS_STRING(result);
1736 Py_MEMCPY(result_s, self_s, self_len);
1737
1738 /* change everything in-place, starting with this one */
1739 start = result_s + (next-self_s);
1740 *start = to_c;
1741 start++;
1742 end = result_s + self_len;
1743
1744 while (--maxcount > 0) {
1745 next = findchar(start, end-start, from_c);
1746 if (next == NULL)
1747 break;
1748 *next = to_c;
1749 start = next+1;
1750 }
1751
1752 return result;
1753}
1754
1755/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1756Py_LOCAL(PyByteArrayObject *)
1757replace_substring_in_place(PyByteArrayObject *self,
1758 const char *from_s, Py_ssize_t from_len,
1759 const char *to_s, Py_ssize_t to_len,
1760 Py_ssize_t maxcount)
1761{
1762 char *result_s, *start, *end;
1763 char *self_s;
1764 Py_ssize_t self_len, offset;
1765 PyByteArrayObject *result;
1766
1767 /* The result bytes will be the same size */
1768
1769 self_s = PyByteArray_AS_STRING(self);
1770 self_len = PyByteArray_GET_SIZE(self);
1771
Antoine Pitrou64672132010-01-13 07:55:48 +00001772 offset = stringlib_find(self_s, self_len,
1773 from_s, from_len,
1774 0);
Christian Heimes44720832008-05-26 13:01:01 +00001775 if (offset == -1) {
1776 /* No matches; return the original bytes */
1777 return return_self(self);
1778 }
1779
1780 /* Need to make a new bytes */
1781 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1782 if (result == NULL)
1783 return NULL;
1784 result_s = PyByteArray_AS_STRING(result);
1785 Py_MEMCPY(result_s, self_s, self_len);
1786
1787 /* change everything in-place, starting with this one */
1788 start = result_s + offset;
1789 Py_MEMCPY(start, to_s, from_len);
1790 start += from_len;
1791 end = result_s + self_len;
1792
1793 while ( --maxcount > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001794 offset = stringlib_find(start, end-start,
1795 from_s, from_len,
1796 0);
Christian Heimes44720832008-05-26 13:01:01 +00001797 if (offset==-1)
1798 break;
1799 Py_MEMCPY(start+offset, to_s, from_len);
1800 start += offset+from_len;
1801 }
1802
1803 return result;
1804}
1805
1806/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1807Py_LOCAL(PyByteArrayObject *)
1808replace_single_character(PyByteArrayObject *self,
1809 char from_c,
1810 const char *to_s, Py_ssize_t to_len,
1811 Py_ssize_t maxcount)
1812{
1813 char *self_s, *result_s;
1814 char *start, *next, *end;
1815 Py_ssize_t self_len, result_len;
1816 Py_ssize_t count, product;
1817 PyByteArrayObject *result;
1818
1819 self_s = PyByteArray_AS_STRING(self);
1820 self_len = PyByteArray_GET_SIZE(self);
1821
1822 count = countchar(self_s, self_len, from_c, maxcount);
1823 if (count == 0) {
1824 /* no matches, return unchanged */
1825 return return_self(self);
1826 }
1827
1828 /* use the difference between current and new, hence the "-1" */
1829 /* result_len = self_len + count * (to_len-1) */
1830 product = count * (to_len-1);
1831 if (product / (to_len-1) != count) {
1832 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1833 return NULL;
1834 }
1835 result_len = self_len + product;
1836 if (result_len < 0) {
1837 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1838 return NULL;
1839 }
1840
1841 if ( (result = (PyByteArrayObject *)
1842 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1843 return NULL;
1844 result_s = PyByteArray_AS_STRING(result);
1845
1846 start = self_s;
1847 end = self_s + self_len;
1848 while (count-- > 0) {
1849 next = findchar(start, end-start, from_c);
1850 if (next == NULL)
1851 break;
1852
1853 if (next == start) {
1854 /* replace with the 'to' */
1855 Py_MEMCPY(result_s, to_s, to_len);
1856 result_s += to_len;
1857 start += 1;
1858 } else {
1859 /* copy the unchanged old then the 'to' */
1860 Py_MEMCPY(result_s, start, next-start);
1861 result_s += (next-start);
1862 Py_MEMCPY(result_s, to_s, to_len);
1863 result_s += to_len;
1864 start = next+1;
1865 }
1866 }
1867 /* Copy the remainder of the remaining bytes */
1868 Py_MEMCPY(result_s, start, end-start);
1869
1870 return result;
1871}
1872
1873/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1874Py_LOCAL(PyByteArrayObject *)
1875replace_substring(PyByteArrayObject *self,
1876 const char *from_s, Py_ssize_t from_len,
1877 const char *to_s, Py_ssize_t to_len,
1878 Py_ssize_t maxcount)
1879{
1880 char *self_s, *result_s;
1881 char *start, *next, *end;
1882 Py_ssize_t self_len, result_len;
1883 Py_ssize_t count, offset, product;
1884 PyByteArrayObject *result;
1885
1886 self_s = PyByteArray_AS_STRING(self);
1887 self_len = PyByteArray_GET_SIZE(self);
1888
Antoine Pitrou64672132010-01-13 07:55:48 +00001889 count = stringlib_count(self_s, self_len,
1890 from_s, from_len,
1891 maxcount);
1892
Christian Heimes44720832008-05-26 13:01:01 +00001893 if (count == 0) {
1894 /* no matches, return unchanged */
1895 return return_self(self);
1896 }
1897
1898 /* Check for overflow */
1899 /* result_len = self_len + count * (to_len-from_len) */
1900 product = count * (to_len-from_len);
1901 if (product / (to_len-from_len) != count) {
1902 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1903 return NULL;
1904 }
1905 result_len = self_len + product;
1906 if (result_len < 0) {
1907 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1908 return NULL;
1909 }
1910
1911 if ( (result = (PyByteArrayObject *)
1912 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1913 return NULL;
1914 result_s = PyByteArray_AS_STRING(result);
1915
1916 start = self_s;
1917 end = self_s + self_len;
1918 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001919 offset = stringlib_find(start, end-start,
1920 from_s, from_len,
1921 0);
Christian Heimes44720832008-05-26 13:01:01 +00001922 if (offset == -1)
1923 break;
1924 next = start+offset;
1925 if (next == start) {
1926 /* replace with the 'to' */
1927 Py_MEMCPY(result_s, to_s, to_len);
1928 result_s += to_len;
1929 start += from_len;
1930 } else {
1931 /* copy the unchanged old then the 'to' */
1932 Py_MEMCPY(result_s, start, next-start);
1933 result_s += (next-start);
1934 Py_MEMCPY(result_s, to_s, to_len);
1935 result_s += to_len;
1936 start = next+from_len;
1937 }
1938 }
1939 /* Copy the remainder of the remaining bytes */
1940 Py_MEMCPY(result_s, start, end-start);
1941
1942 return result;
1943}
1944
1945
1946Py_LOCAL(PyByteArrayObject *)
1947replace(PyByteArrayObject *self,
1948 const char *from_s, Py_ssize_t from_len,
1949 const char *to_s, Py_ssize_t to_len,
1950 Py_ssize_t maxcount)
1951{
1952 if (maxcount < 0) {
1953 maxcount = PY_SSIZE_T_MAX;
1954 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1955 /* nothing to do; return the original bytes */
1956 return return_self(self);
1957 }
1958
1959 if (maxcount == 0 ||
1960 (from_len == 0 && to_len == 0)) {
1961 /* nothing to do; return the original bytes */
1962 return return_self(self);
1963 }
1964
1965 /* Handle zero-length special cases */
1966
1967 if (from_len == 0) {
1968 /* insert the 'to' bytes everywhere. */
1969 /* >>> "Python".replace("", ".") */
1970 /* '.P.y.t.h.o.n.' */
1971 return replace_interleave(self, to_s, to_len, maxcount);
1972 }
1973
1974 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1975 /* point for an empty self bytes to generate a non-empty bytes */
1976 /* Special case so the remaining code always gets a non-empty bytes */
1977 if (PyByteArray_GET_SIZE(self) == 0) {
1978 return return_self(self);
1979 }
1980
1981 if (to_len == 0) {
1982 /* delete all occurances of 'from' bytes */
1983 if (from_len == 1) {
1984 return replace_delete_single_character(
1985 self, from_s[0], maxcount);
1986 } else {
1987 return replace_delete_substring(self, from_s, from_len, maxcount);
1988 }
1989 }
1990
1991 /* Handle special case where both bytes have the same length */
1992
1993 if (from_len == to_len) {
1994 if (from_len == 1) {
1995 return replace_single_character_in_place(
1996 self,
1997 from_s[0],
1998 to_s[0],
1999 maxcount);
2000 } else {
2001 return replace_substring_in_place(
2002 self, from_s, from_len, to_s, to_len, maxcount);
2003 }
2004 }
2005
2006 /* Otherwise use the more generic algorithms */
2007 if (from_len == 1) {
2008 return replace_single_character(self, from_s[0],
2009 to_s, to_len, maxcount);
2010 } else {
2011 /* len('from')>=2, len('to')>=1 */
2012 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2013 }
2014}
2015
2016
2017PyDoc_STRVAR(replace__doc__,
2018"B.replace(old, new[, count]) -> bytes\n\
2019\n\
2020Return a copy of B with all occurrences of subsection\n\
2021old replaced by new. If the optional argument count is\n\
2022given, only the first count occurrences are replaced.");
2023
2024static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002025bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002026{
2027 Py_ssize_t count = -1;
2028 PyObject *from, *to, *res;
2029 Py_buffer vfrom, vto;
2030
2031 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2032 return NULL;
2033
2034 if (_getbuffer(from, &vfrom) < 0)
2035 return NULL;
2036 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002037 PyBuffer_Release(&vfrom);
Christian Heimes44720832008-05-26 13:01:01 +00002038 return NULL;
2039 }
2040
2041 res = (PyObject *)replace((PyByteArrayObject *) self,
2042 vfrom.buf, vfrom.len,
2043 vto.buf, vto.len, count);
2044
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002045 PyBuffer_Release(&vfrom);
2046 PyBuffer_Release(&vto);
Christian Heimes44720832008-05-26 13:01:01 +00002047 return res;
2048}
2049
Christian Heimes44720832008-05-26 13:01:01 +00002050PyDoc_STRVAR(split__doc__,
2051"B.split([sep[, maxsplit]]) -> list of bytearray\n\
2052\n\
2053Return a list of the sections in B, using sep as the delimiter.\n\
2054If sep is not given, B is split on ASCII whitespace characters\n\
2055(space, tab, return, newline, formfeed, vertical tab).\n\
2056If maxsplit is given, at most maxsplit splits are done.");
2057
2058static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002059bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002060{
Antoine Pitrou64672132010-01-13 07:55:48 +00002061 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2062 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002063 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002064 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002065 Py_buffer vsub;
Christian Heimes44720832008-05-26 13:01:01 +00002066
2067 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2068 return NULL;
2069 if (maxsplit < 0)
2070 maxsplit = PY_SSIZE_T_MAX;
2071
2072 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002073 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002074
2075 if (_getbuffer(subobj, &vsub) < 0)
2076 return NULL;
2077 sub = vsub.buf;
2078 n = vsub.len;
2079
Antoine Pitrou64672132010-01-13 07:55:48 +00002080 list = stringlib_split(
2081 (PyObject*) self, s, len, sub, n, maxsplit
2082 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002083 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002084 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002085}
2086
2087PyDoc_STRVAR(partition__doc__,
2088"B.partition(sep) -> (head, sep, tail)\n\
2089\n\
2090Searches for the separator sep in B, and returns the part before it,\n\
2091the separator itself, and the part after it. If the separator is not\n\
2092found, returns B and two empty bytearray objects.");
2093
2094static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002095bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002096{
2097 PyObject *bytesep, *result;
2098
2099 bytesep = PyByteArray_FromObject(sep_obj);
2100 if (! bytesep)
2101 return NULL;
2102
2103 result = stringlib_partition(
2104 (PyObject*) self,
2105 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2106 bytesep,
2107 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2108 );
2109
2110 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002111 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002112}
2113
2114PyDoc_STRVAR(rpartition__doc__,
2115"B.rpartition(sep) -> (tail, sep, head)\n\
2116\n\
2117Searches for the separator sep in B, starting at the end of B,\n\
2118and returns the part before it, the separator itself, and the\n\
2119part after it. If the separator is not found, returns two empty\n\
2120bytearray objects and B.");
2121
2122static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002123bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002124{
2125 PyObject *bytesep, *result;
2126
2127 bytesep = PyByteArray_FromObject(sep_obj);
2128 if (! bytesep)
2129 return NULL;
2130
2131 result = stringlib_rpartition(
2132 (PyObject*) self,
2133 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2134 bytesep,
2135 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2136 );
2137
2138 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002139 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002140}
2141
2142PyDoc_STRVAR(rsplit__doc__,
2143"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2144\n\
2145Return a list of the sections in B, using sep as the delimiter,\n\
2146starting at the end of B and working to the front.\n\
2147If sep is not given, B is split on ASCII whitespace characters\n\
2148(space, tab, return, newline, formfeed, vertical tab).\n\
2149If maxsplit is given, at most maxsplit splits are done.");
2150
2151static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002152bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002153{
Antoine Pitrou64672132010-01-13 07:55:48 +00002154 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2155 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002156 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002157 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002158 Py_buffer vsub;
2159
2160 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2161 return NULL;
2162 if (maxsplit < 0)
2163 maxsplit = PY_SSIZE_T_MAX;
2164
2165 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002166 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002167
2168 if (_getbuffer(subobj, &vsub) < 0)
2169 return NULL;
2170 sub = vsub.buf;
2171 n = vsub.len;
2172
Antoine Pitrou64672132010-01-13 07:55:48 +00002173 list = stringlib_rsplit(
2174 (PyObject*) self, s, len, sub, n, maxsplit
2175 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002176 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002177 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002178}
2179
2180PyDoc_STRVAR(reverse__doc__,
2181"B.reverse() -> None\n\
2182\n\
2183Reverse the order of the values in B in place.");
2184static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002185bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes44720832008-05-26 13:01:01 +00002186{
2187 char swap, *head, *tail;
2188 Py_ssize_t i, j, n = Py_SIZE(self);
2189
2190 j = n / 2;
2191 head = self->ob_bytes;
2192 tail = head + n - 1;
2193 for (i = 0; i < j; i++) {
2194 swap = *head;
2195 *head++ = *tail;
2196 *tail-- = swap;
2197 }
2198
2199 Py_RETURN_NONE;
2200}
2201
2202PyDoc_STRVAR(insert__doc__,
2203"B.insert(index, int) -> None\n\
2204\n\
2205Insert a single item into the bytearray before the given index.");
2206static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002207bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002208{
Georg Brandl3e483f62008-07-16 22:57:41 +00002209 PyObject *value;
2210 int ival;
Christian Heimes44720832008-05-26 13:01:01 +00002211 Py_ssize_t where, n = Py_SIZE(self);
2212
Georg Brandl3e483f62008-07-16 22:57:41 +00002213 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes44720832008-05-26 13:01:01 +00002214 return NULL;
2215
2216 if (n == PY_SSIZE_T_MAX) {
2217 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002218 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002219 return NULL;
2220 }
Georg Brandl3e483f62008-07-16 22:57:41 +00002221 if (!_getbytevalue(value, &ival))
Christian Heimes44720832008-05-26 13:01:01 +00002222 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002223 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2224 return NULL;
2225
2226 if (where < 0) {
2227 where += n;
2228 if (where < 0)
2229 where = 0;
2230 }
2231 if (where > n)
2232 where = n;
2233 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl3e483f62008-07-16 22:57:41 +00002234 self->ob_bytes[where] = ival;
Christian Heimes44720832008-05-26 13:01:01 +00002235
2236 Py_RETURN_NONE;
2237}
2238
2239PyDoc_STRVAR(append__doc__,
2240"B.append(int) -> None\n\
2241\n\
2242Append a single item to the end of B.");
2243static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002244bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002245{
2246 int value;
2247 Py_ssize_t n = Py_SIZE(self);
2248
2249 if (! _getbytevalue(arg, &value))
2250 return NULL;
2251 if (n == PY_SSIZE_T_MAX) {
2252 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002253 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002254 return NULL;
2255 }
2256 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2257 return NULL;
2258
2259 self->ob_bytes[n] = value;
2260
2261 Py_RETURN_NONE;
2262}
2263
2264PyDoc_STRVAR(extend__doc__,
2265"B.extend(iterable int) -> None\n\
2266\n\
2267Append all the elements from the iterator or sequence to the\n\
2268end of B.");
2269static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002270bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002271{
Benjamin Petersond6720012009-04-18 15:31:34 +00002272 PyObject *it, *item, *bytearray_obj;
Christian Heimes44720832008-05-26 13:01:01 +00002273 Py_ssize_t buf_size = 0, len = 0;
2274 int value;
2275 char *buf;
2276
Benjamin Petersond6720012009-04-18 15:31:34 +00002277 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes44720832008-05-26 13:01:01 +00002278 if (PyObject_CheckBuffer(arg)) {
Benjamin Petersond6720012009-04-18 15:31:34 +00002279 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002280 return NULL;
2281
2282 Py_RETURN_NONE;
2283 }
2284
2285 it = PyObject_GetIter(arg);
2286 if (it == NULL)
2287 return NULL;
2288
2289 /* Try to determine the length of the argument. 32 is abitrary. */
2290 buf_size = _PyObject_LengthHint(arg, 32);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002291 if (buf_size == -1) {
2292 Py_DECREF(it);
2293 return NULL;
2294 }
Christian Heimes44720832008-05-26 13:01:01 +00002295
Benjamin Petersond6720012009-04-18 15:31:34 +00002296 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2297 if (bytearray_obj == NULL)
Christian Heimes44720832008-05-26 13:01:01 +00002298 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002299 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002300
2301 while ((item = PyIter_Next(it)) != NULL) {
2302 if (! _getbytevalue(item, &value)) {
2303 Py_DECREF(item);
2304 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002305 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002306 return NULL;
2307 }
2308 buf[len++] = value;
2309 Py_DECREF(item);
2310
2311 if (len >= buf_size) {
2312 buf_size = len + (len >> 1) + 1;
Benjamin Petersond6720012009-04-18 15:31:34 +00002313 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00002314 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002315 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002316 return NULL;
2317 }
2318 /* Recompute the `buf' pointer, since the resizing operation may
2319 have invalidated it. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002320 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002321 }
2322 }
2323 Py_DECREF(it);
2324
2325 /* Resize down to exact size. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002326 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2327 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002328 return NULL;
2329 }
2330
Benjamin Petersond6720012009-04-18 15:31:34 +00002331 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002332 return NULL;
Benjamin Petersond6720012009-04-18 15:31:34 +00002333 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002334
2335 Py_RETURN_NONE;
2336}
2337
2338PyDoc_STRVAR(pop__doc__,
2339"B.pop([index]) -> int\n\
2340\n\
2341Remove and return a single item from B. If no index\n\
Andrew M. Kuchlingd8972642008-06-21 13:29:12 +00002342argument is given, will pop the last value.");
Christian Heimes44720832008-05-26 13:01:01 +00002343static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002344bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002345{
2346 int value;
2347 Py_ssize_t where = -1, n = Py_SIZE(self);
2348
2349 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2350 return NULL;
2351
2352 if (n == 0) {
2353 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002354 "cannot pop an empty bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002355 return NULL;
2356 }
2357 if (where < 0)
2358 where += Py_SIZE(self);
2359 if (where < 0 || where >= Py_SIZE(self)) {
2360 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2361 return NULL;
2362 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002363 if (!_canresize(self))
2364 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002365
2366 value = self->ob_bytes[where];
2367 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2368 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2369 return NULL;
2370
Mark Dickinsonc8a7c7c2009-09-06 10:03:31 +00002371 return PyInt_FromLong((unsigned char)value);
Christian Heimes44720832008-05-26 13:01:01 +00002372}
2373
2374PyDoc_STRVAR(remove__doc__,
2375"B.remove(int) -> None\n\
2376\n\
2377Remove the first occurance of a value in B.");
2378static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002379bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002380{
2381 int value;
2382 Py_ssize_t where, n = Py_SIZE(self);
2383
2384 if (! _getbytevalue(arg, &value))
2385 return NULL;
2386
2387 for (where = 0; where < n; where++) {
2388 if (self->ob_bytes[where] == value)
2389 break;
2390 }
2391 if (where == n) {
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002392 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002393 return NULL;
2394 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002395 if (!_canresize(self))
2396 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002397
2398 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2399 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2400 return NULL;
2401
2402 Py_RETURN_NONE;
2403}
2404
2405/* XXX These two helpers could be optimized if argsize == 1 */
2406
2407static Py_ssize_t
2408lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2409 void *argptr, Py_ssize_t argsize)
2410{
2411 Py_ssize_t i = 0;
2412 while (i < mysize && memchr(argptr, myptr[i], argsize))
2413 i++;
2414 return i;
2415}
2416
2417static Py_ssize_t
2418rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2419 void *argptr, Py_ssize_t argsize)
2420{
2421 Py_ssize_t i = mysize - 1;
2422 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2423 i--;
2424 return i + 1;
2425}
2426
2427PyDoc_STRVAR(strip__doc__,
2428"B.strip([bytes]) -> bytearray\n\
2429\n\
2430Strip leading and trailing bytes contained in the argument.\n\
2431If the argument is omitted, strip ASCII whitespace.");
2432static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002433bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002434{
2435 Py_ssize_t left, right, mysize, argsize;
2436 void *myptr, *argptr;
2437 PyObject *arg = Py_None;
2438 Py_buffer varg;
2439 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2440 return NULL;
2441 if (arg == Py_None) {
2442 argptr = "\t\n\r\f\v ";
2443 argsize = 6;
2444 }
2445 else {
2446 if (_getbuffer(arg, &varg) < 0)
2447 return NULL;
2448 argptr = varg.buf;
2449 argsize = varg.len;
2450 }
2451 myptr = self->ob_bytes;
2452 mysize = Py_SIZE(self);
2453 left = lstrip_helper(myptr, mysize, argptr, argsize);
2454 if (left == mysize)
2455 right = left;
2456 else
2457 right = rstrip_helper(myptr, mysize, argptr, argsize);
2458 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002459 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002460 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2461}
2462
2463PyDoc_STRVAR(lstrip__doc__,
2464"B.lstrip([bytes]) -> bytearray\n\
2465\n\
2466Strip leading bytes contained in the argument.\n\
2467If the argument is omitted, strip leading ASCII whitespace.");
2468static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002469bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002470{
2471 Py_ssize_t left, right, mysize, argsize;
2472 void *myptr, *argptr;
2473 PyObject *arg = Py_None;
2474 Py_buffer varg;
2475 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2476 return NULL;
2477 if (arg == Py_None) {
2478 argptr = "\t\n\r\f\v ";
2479 argsize = 6;
2480 }
2481 else {
2482 if (_getbuffer(arg, &varg) < 0)
2483 return NULL;
2484 argptr = varg.buf;
2485 argsize = varg.len;
2486 }
2487 myptr = self->ob_bytes;
2488 mysize = Py_SIZE(self);
2489 left = lstrip_helper(myptr, mysize, argptr, argsize);
2490 right = mysize;
2491 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002492 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002493 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2494}
2495
2496PyDoc_STRVAR(rstrip__doc__,
2497"B.rstrip([bytes]) -> bytearray\n\
2498\n\
2499Strip trailing bytes contained in the argument.\n\
2500If the argument is omitted, strip trailing ASCII whitespace.");
2501static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002502bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002503{
2504 Py_ssize_t left, right, mysize, argsize;
2505 void *myptr, *argptr;
2506 PyObject *arg = Py_None;
2507 Py_buffer varg;
2508 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2509 return NULL;
2510 if (arg == Py_None) {
2511 argptr = "\t\n\r\f\v ";
2512 argsize = 6;
2513 }
2514 else {
2515 if (_getbuffer(arg, &varg) < 0)
2516 return NULL;
2517 argptr = varg.buf;
2518 argsize = varg.len;
2519 }
2520 myptr = self->ob_bytes;
2521 mysize = Py_SIZE(self);
2522 left = 0;
2523 right = rstrip_helper(myptr, mysize, argptr, argsize);
2524 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002525 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002526 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2527}
2528
2529PyDoc_STRVAR(decode_doc,
2530"B.decode([encoding[, errors]]) -> unicode object.\n\
2531\n\
2532Decodes B using the codec registered for encoding. encoding defaults\n\
2533to the default encoding. errors may be given to set a different error\n\
2534handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2535a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2536as well as any other name registered with codecs.register_error that is\n\
2537able to handle UnicodeDecodeErrors.");
2538
2539static PyObject *
Benjamin Petersondc782b52009-09-18 21:46:21 +00002540bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes44720832008-05-26 13:01:01 +00002541{
2542 const char *encoding = NULL;
2543 const char *errors = NULL;
Benjamin Petersondc782b52009-09-18 21:46:21 +00002544 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes44720832008-05-26 13:01:01 +00002545
Benjamin Petersondc782b52009-09-18 21:46:21 +00002546 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes44720832008-05-26 13:01:01 +00002547 return NULL;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002548 if (encoding == NULL) {
2549#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002550 encoding = PyUnicode_GetDefaultEncoding();
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002551#else
2552 PyErr_SetString(PyExc_ValueError, "no encoding specified");
2553 return NULL;
2554#endif
2555 }
Christian Heimes44720832008-05-26 13:01:01 +00002556 return PyCodec_Decode(self, encoding, errors);
2557}
2558
2559PyDoc_STRVAR(alloc_doc,
2560"B.__alloc__() -> int\n\
2561\n\
2562Returns the number of bytes actually allocated.");
2563
2564static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002565bytearray_alloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002566{
2567 return PyInt_FromSsize_t(self->ob_alloc);
2568}
2569
2570PyDoc_STRVAR(join_doc,
2571"B.join(iterable_of_bytes) -> bytes\n\
2572\n\
2573Concatenates any number of bytearray objects, with B in between each pair.");
2574
2575static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002576bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002577{
2578 PyObject *seq;
2579 Py_ssize_t mysize = Py_SIZE(self);
2580 Py_ssize_t i;
2581 Py_ssize_t n;
2582 PyObject **items;
2583 Py_ssize_t totalsize = 0;
2584 PyObject *result;
2585 char *dest;
2586
2587 seq = PySequence_Fast(it, "can only join an iterable");
2588 if (seq == NULL)
2589 return NULL;
2590 n = PySequence_Fast_GET_SIZE(seq);
2591 items = PySequence_Fast_ITEMS(seq);
2592
2593 /* Compute the total size, and check that they are all bytes */
2594 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2595 for (i = 0; i < n; i++) {
2596 PyObject *obj = items[i];
2597 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2598 PyErr_Format(PyExc_TypeError,
2599 "can only join an iterable of bytes "
2600 "(item %ld has type '%.100s')",
2601 /* XXX %ld isn't right on Win64 */
2602 (long)i, Py_TYPE(obj)->tp_name);
2603 goto error;
2604 }
2605 if (i > 0)
2606 totalsize += mysize;
2607 totalsize += Py_SIZE(obj);
2608 if (totalsize < 0) {
2609 PyErr_NoMemory();
2610 goto error;
2611 }
2612 }
2613
2614 /* Allocate the result, and copy the bytes */
2615 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2616 if (result == NULL)
2617 goto error;
2618 dest = PyByteArray_AS_STRING(result);
2619 for (i = 0; i < n; i++) {
2620 PyObject *obj = items[i];
2621 Py_ssize_t size = Py_SIZE(obj);
2622 char *buf;
2623 if (PyByteArray_Check(obj))
2624 buf = PyByteArray_AS_STRING(obj);
2625 else
2626 buf = PyBytes_AS_STRING(obj);
2627 if (i) {
2628 memcpy(dest, self->ob_bytes, mysize);
2629 dest += mysize;
2630 }
2631 memcpy(dest, buf, size);
2632 dest += size;
2633 }
2634
2635 /* Done */
2636 Py_DECREF(seq);
2637 return result;
2638
2639 /* Error handling */
2640 error:
2641 Py_DECREF(seq);
2642 return NULL;
2643}
2644
Antoine Pitrou64672132010-01-13 07:55:48 +00002645PyDoc_STRVAR(splitlines__doc__,
2646"B.splitlines([keepends]) -> list of lines\n\
2647\n\
2648Return a list of the lines in B, breaking at line boundaries.\n\
2649Line breaks are not included in the resulting list unless keepends\n\
2650is given and true.");
2651
2652static PyObject*
2653bytearray_splitlines(PyObject *self, PyObject *args)
2654{
2655 int keepends = 0;
2656
2657 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2658 return NULL;
2659
2660 return stringlib_splitlines(
2661 (PyObject*) self, PyByteArray_AS_STRING(self),
2662 PyByteArray_GET_SIZE(self), keepends
2663 );
2664}
2665
Christian Heimes44720832008-05-26 13:01:01 +00002666PyDoc_STRVAR(fromhex_doc,
2667"bytearray.fromhex(string) -> bytearray\n\
2668\n\
2669Create a bytearray object from a string of hexadecimal numbers.\n\
2670Spaces between two numbers are accepted.\n\
2671Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2672
2673static int
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002674hex_digit_to_int(char c)
Christian Heimes44720832008-05-26 13:01:01 +00002675{
Eric Smithcac7af62009-04-27 19:04:37 +00002676 if (Py_ISDIGIT(c))
Christian Heimes44720832008-05-26 13:01:01 +00002677 return c - '0';
2678 else {
Eric Smithcac7af62009-04-27 19:04:37 +00002679 if (Py_ISUPPER(c))
2680 c = Py_TOLOWER(c);
Christian Heimes44720832008-05-26 13:01:01 +00002681 if (c >= 'a' && c <= 'f')
2682 return c - 'a' + 10;
2683 }
2684 return -1;
2685}
2686
2687static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002688bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002689{
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002690 PyObject *newbytes;
Christian Heimes44720832008-05-26 13:01:01 +00002691 char *buf;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002692 char *hex;
Christian Heimes44720832008-05-26 13:01:01 +00002693 Py_ssize_t hexlen, byteslen, i, j;
2694 int top, bot;
2695
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002696 if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
Christian Heimes44720832008-05-26 13:01:01 +00002697 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002698 byteslen = hexlen/2; /* This overestimates if there are spaces */
2699 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2700 if (!newbytes)
2701 return NULL;
2702 buf = PyByteArray_AS_STRING(newbytes);
2703 for (i = j = 0; i < hexlen; i += 2) {
2704 /* skip over spaces in the input */
2705 while (hex[i] == ' ')
2706 i++;
2707 if (i >= hexlen)
2708 break;
2709 top = hex_digit_to_int(hex[i]);
2710 bot = hex_digit_to_int(hex[i+1]);
2711 if (top == -1 || bot == -1) {
2712 PyErr_Format(PyExc_ValueError,
2713 "non-hexadecimal number found in "
2714 "fromhex() arg at position %zd", i);
2715 goto error;
2716 }
2717 buf[j++] = (top << 4) + bot;
2718 }
2719 if (PyByteArray_Resize(newbytes, j) < 0)
2720 goto error;
2721 return newbytes;
2722
2723 error:
2724 Py_DECREF(newbytes);
2725 return NULL;
2726}
2727
2728PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2729
2730static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002731bytearray_reduce(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002732{
2733 PyObject *latin1, *dict;
2734 if (self->ob_bytes)
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002735#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002736 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2737 Py_SIZE(self), NULL);
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002738#else
Mark Dickinson9d109742009-10-15 15:18:55 +00002739 latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002740#endif
Christian Heimes44720832008-05-26 13:01:01 +00002741 else
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002742#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002743 latin1 = PyUnicode_FromString("");
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002744#else
2745 latin1 = PyString_FromString("");
2746#endif
Christian Heimes44720832008-05-26 13:01:01 +00002747
2748 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2749 if (dict == NULL) {
2750 PyErr_Clear();
2751 dict = Py_None;
2752 Py_INCREF(dict);
2753 }
2754
2755 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2756}
2757
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002758PyDoc_STRVAR(sizeof_doc,
2759"B.__sizeof__() -> int\n\
2760 \n\
2761Returns the size of B in memory, in bytes");
2762static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002763bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002764{
Georg Brandl517cfdc2009-04-05 13:16:35 +00002765 Py_ssize_t res;
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002766
Georg Brandl517cfdc2009-04-05 13:16:35 +00002767 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2768 return PyInt_FromSsize_t(res);
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002769}
2770
Benjamin Petersond6720012009-04-18 15:31:34 +00002771static PySequenceMethods bytearray_as_sequence = {
2772 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes44720832008-05-26 13:01:01 +00002773 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Petersond6720012009-04-18 15:31:34 +00002774 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2775 (ssizeargfunc)bytearray_getitem, /* sq_item */
2776 0, /* sq_slice */
2777 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2778 0, /* sq_ass_slice */
2779 (objobjproc)bytearray_contains, /* sq_contains */
2780 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2781 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes44720832008-05-26 13:01:01 +00002782};
2783
Benjamin Petersond6720012009-04-18 15:31:34 +00002784static PyMappingMethods bytearray_as_mapping = {
2785 (lenfunc)bytearray_length,
2786 (binaryfunc)bytearray_subscript,
2787 (objobjargproc)bytearray_ass_subscript,
Christian Heimes44720832008-05-26 13:01:01 +00002788};
2789
Benjamin Petersond6720012009-04-18 15:31:34 +00002790static PyBufferProcs bytearray_as_buffer = {
2791 (readbufferproc)bytearray_buffer_getreadbuf,
2792 (writebufferproc)bytearray_buffer_getwritebuf,
2793 (segcountproc)bytearray_buffer_getsegcount,
2794 (charbufferproc)bytearray_buffer_getcharbuf,
2795 (getbufferproc)bytearray_getbuffer,
2796 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes44720832008-05-26 13:01:01 +00002797};
2798
2799static PyMethodDef
Benjamin Petersond6720012009-04-18 15:31:34 +00002800bytearray_methods[] = {
2801 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2802 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2803 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2804 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002805 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2806 _Py_capitalize__doc__},
2807 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002808 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Petersondc782b52009-09-18 21:46:21 +00002809 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002810 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002811 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2812 expandtabs__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002813 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2814 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2815 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes44720832008-05-26 13:01:01 +00002816 fromhex_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002817 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2818 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002819 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2820 _Py_isalnum__doc__},
2821 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2822 _Py_isalpha__doc__},
2823 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2824 _Py_isdigit__doc__},
2825 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2826 _Py_islower__doc__},
2827 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2828 _Py_isspace__doc__},
2829 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2830 _Py_istitle__doc__},
2831 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2832 _Py_isupper__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002833 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes44720832008-05-26 13:01:01 +00002834 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2835 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002836 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2837 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2838 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2839 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2840 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2841 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2842 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2843 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002844 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002845 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2846 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2847 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2848 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrou64672132010-01-13 07:55:48 +00002849 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002850 splitlines__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002851 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes44720832008-05-26 13:01:01 +00002852 startswith__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002853 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002854 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2855 _Py_swapcase__doc__},
2856 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002857 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002858 translate__doc__},
2859 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2860 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2861 {NULL}
2862};
2863
Benjamin Petersond6720012009-04-18 15:31:34 +00002864PyDoc_STRVAR(bytearray_doc,
Christian Heimes44720832008-05-26 13:01:01 +00002865"bytearray(iterable_of_ints) -> bytearray.\n\
2866bytearray(string, encoding[, errors]) -> bytearray.\n\
2867bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
2868bytearray(memory_view) -> bytearray.\n\
2869\n\
2870Construct an mutable bytearray object from:\n\
2871 - an iterable yielding integers in range(256)\n\
2872 - a text string encoded using the specified encoding\n\
2873 - a bytes or a bytearray object\n\
2874 - any object implementing the buffer API.\n\
2875\n\
2876bytearray(int) -> bytearray.\n\
2877\n\
2878Construct a zero-initialized bytearray of the given length.");
2879
2880
Benjamin Petersond6720012009-04-18 15:31:34 +00002881static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes44720832008-05-26 13:01:01 +00002882
2883PyTypeObject PyByteArray_Type = {
2884 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2885 "bytearray",
2886 sizeof(PyByteArrayObject),
2887 0,
Benjamin Petersond6720012009-04-18 15:31:34 +00002888 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00002889 0, /* tp_print */
2890 0, /* tp_getattr */
2891 0, /* tp_setattr */
2892 0, /* tp_compare */
Benjamin Petersond6720012009-04-18 15:31:34 +00002893 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes44720832008-05-26 13:01:01 +00002894 0, /* tp_as_number */
Benjamin Petersond6720012009-04-18 15:31:34 +00002895 &bytearray_as_sequence, /* tp_as_sequence */
2896 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes44720832008-05-26 13:01:01 +00002897 0, /* tp_hash */
2898 0, /* tp_call */
Benjamin Petersond6720012009-04-18 15:31:34 +00002899 bytearray_str, /* tp_str */
Christian Heimes44720832008-05-26 13:01:01 +00002900 PyObject_GenericGetAttr, /* tp_getattro */
2901 0, /* tp_setattro */
Benjamin Petersond6720012009-04-18 15:31:34 +00002902 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes44720832008-05-26 13:01:01 +00002903 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2904 Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
Benjamin Petersond6720012009-04-18 15:31:34 +00002905 bytearray_doc, /* tp_doc */
Christian Heimes44720832008-05-26 13:01:01 +00002906 0, /* tp_traverse */
2907 0, /* tp_clear */
Benjamin Petersond6720012009-04-18 15:31:34 +00002908 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes44720832008-05-26 13:01:01 +00002909 0, /* tp_weaklistoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002910 bytearray_iter, /* tp_iter */
Christian Heimes44720832008-05-26 13:01:01 +00002911 0, /* tp_iternext */
Benjamin Petersond6720012009-04-18 15:31:34 +00002912 bytearray_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00002913 0, /* tp_members */
2914 0, /* tp_getset */
2915 0, /* tp_base */
2916 0, /* tp_dict */
2917 0, /* tp_descr_get */
2918 0, /* tp_descr_set */
2919 0, /* tp_dictoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002920 (initproc)bytearray_init, /* tp_init */
Christian Heimes44720832008-05-26 13:01:01 +00002921 PyType_GenericAlloc, /* tp_alloc */
2922 PyType_GenericNew, /* tp_new */
2923 PyObject_Del, /* tp_free */
2924};
2925
2926/*********************** Bytes Iterator ****************************/
2927
2928typedef struct {
2929 PyObject_HEAD
2930 Py_ssize_t it_index;
2931 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2932} bytesiterobject;
2933
2934static void
Benjamin Petersond6720012009-04-18 15:31:34 +00002935bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002936{
2937 _PyObject_GC_UNTRACK(it);
2938 Py_XDECREF(it->it_seq);
2939 PyObject_GC_Del(it);
2940}
2941
2942static int
Benjamin Petersond6720012009-04-18 15:31:34 +00002943bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002944{
2945 Py_VISIT(it->it_seq);
2946 return 0;
2947}
2948
2949static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002950bytearrayiter_next(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002951{
2952 PyByteArrayObject *seq;
2953 PyObject *item;
2954
2955 assert(it != NULL);
2956 seq = it->it_seq;
2957 if (seq == NULL)
2958 return NULL;
2959 assert(PyByteArray_Check(seq));
2960
2961 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2962 item = PyInt_FromLong(
2963 (unsigned char)seq->ob_bytes[it->it_index]);
2964 if (item != NULL)
2965 ++it->it_index;
2966 return item;
2967 }
2968
2969 Py_DECREF(seq);
2970 it->it_seq = NULL;
2971 return NULL;
2972}
2973
2974static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002975bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002976{
2977 Py_ssize_t len = 0;
2978 if (it->it_seq)
2979 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2980 return PyInt_FromSsize_t(len);
2981}
2982
2983PyDoc_STRVAR(length_hint_doc,
2984 "Private method returning an estimate of len(list(it)).");
2985
Benjamin Petersond6720012009-04-18 15:31:34 +00002986static PyMethodDef bytearrayiter_methods[] = {
2987 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002988 length_hint_doc},
2989 {NULL, NULL} /* sentinel */
2990};
2991
2992PyTypeObject PyByteArrayIter_Type = {
2993 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2994 "bytearray_iterator", /* tp_name */
2995 sizeof(bytesiterobject), /* tp_basicsize */
2996 0, /* tp_itemsize */
2997 /* methods */
Benjamin Petersond6720012009-04-18 15:31:34 +00002998 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00002999 0, /* tp_print */
3000 0, /* tp_getattr */
3001 0, /* tp_setattr */
3002 0, /* tp_compare */
3003 0, /* tp_repr */
3004 0, /* tp_as_number */
3005 0, /* tp_as_sequence */
3006 0, /* tp_as_mapping */
3007 0, /* tp_hash */
3008 0, /* tp_call */
3009 0, /* tp_str */
3010 PyObject_GenericGetAttr, /* tp_getattro */
3011 0, /* tp_setattro */
3012 0, /* tp_as_buffer */
3013 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3014 0, /* tp_doc */
Benjamin Petersond6720012009-04-18 15:31:34 +00003015 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes44720832008-05-26 13:01:01 +00003016 0, /* tp_clear */
3017 0, /* tp_richcompare */
3018 0, /* tp_weaklistoffset */
3019 PyObject_SelfIter, /* tp_iter */
Benjamin Petersond6720012009-04-18 15:31:34 +00003020 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3021 bytearrayiter_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00003022 0,
3023};
3024
3025static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003026bytearray_iter(PyObject *seq)
Christian Heimes44720832008-05-26 13:01:01 +00003027{
3028 bytesiterobject *it;
3029
3030 if (!PyByteArray_Check(seq)) {
3031 PyErr_BadInternalCall();
3032 return NULL;
3033 }
3034 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3035 if (it == NULL)
3036 return NULL;
3037 it->it_index = 0;
3038 Py_INCREF(seq);
3039 it->it_seq = (PyByteArrayObject *)seq;
3040 _PyObject_GC_TRACK(it);
3041 return (PyObject *)it;
3042}