blob: 021ab1a5310de2e386ea4ea6aa223371353643e9 [file] [log] [blame]
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001/* PyByteArray (bytearray) implementation */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
5#include "structmember.h"
6#include "bytes_methods.h"
7
Antoine Pitroufc8d6f42010-01-17 12:38:54 +00008char _PyByteArray_empty_string[] = "";
Christian Heimes2c9c7a52008-05-26 13:42:13 +00009
10void
11PyByteArray_Fini(void)
12{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000013}
14
15int
16PyByteArray_Init(void)
17{
Christian Heimes2c9c7a52008-05-26 13:42:13 +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
30 if (PyLong_Check(arg)) {
31 face_value = PyLong_AsLong(arg);
Georg Brandl9a54d7c2008-07-16 23:15:30 +000032 } else {
33 PyObject *index = PyNumber_Index(arg);
34 if (index == NULL) {
35 PyErr_Format(PyExc_TypeError, "an integer is required");
Mark Dickinson10de93a2010-07-09 19:25:48 +000036 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000037 return 0;
38 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +000039 face_value = PyLong_AsLong(index);
40 Py_DECREF(index);
41 }
42
43 if (face_value < 0 || face_value >= 256) {
44 /* this includes the OverflowError in case the long is too large */
45 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Mark Dickinson10de93a2010-07-09 19:25:48 +000046 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000047 return 0;
48 }
49
50 *value = face_value;
51 return 1;
52}
53
54static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +000055bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000056{
57 int ret;
58 void *ptr;
59 if (view == NULL) {
60 obj->ob_exports++;
61 return 0;
62 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000063 ptr = (void *) PyByteArray_AS_STRING(obj);
Martin v. Löwis423be952008-08-13 15:53:07 +000064 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
Christian Heimes2c9c7a52008-05-26 13:42:13 +000065 if (ret >= 0) {
66 obj->ob_exports++;
67 }
68 return ret;
69}
70
71static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +000072bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000073{
74 obj->ob_exports--;
75}
76
77static Py_ssize_t
78_getbuffer(PyObject *obj, Py_buffer *view)
79{
80 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
81
82 if (buffer == NULL || buffer->bf_getbuffer == NULL)
83 {
84 PyErr_Format(PyExc_TypeError,
85 "Type %.100s doesn't support the buffer API",
86 Py_TYPE(obj)->tp_name);
87 return -1;
88 }
89
90 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
91 return -1;
92 return view->len;
93}
94
Antoine Pitrou5504e892008-12-06 21:27:53 +000095static int
96_canresize(PyByteArrayObject *self)
97{
98 if (self->ob_exports > 0) {
99 PyErr_SetString(PyExc_BufferError,
100 "Existing exports of data: object cannot be re-sized");
101 return 0;
102 }
103 return 1;
104}
105
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000106/* Direct API functions */
107
108PyObject *
109PyByteArray_FromObject(PyObject *input)
110{
111 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
112 input, NULL);
113}
114
115PyObject *
116PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
117{
118 PyByteArrayObject *new;
119 Py_ssize_t alloc;
120
121 if (size < 0) {
122 PyErr_SetString(PyExc_SystemError,
123 "Negative size passed to PyByteArray_FromStringAndSize");
124 return NULL;
125 }
126
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000127 /* Prevent buffer overflow when setting alloc to size+1. */
128 if (size == PY_SSIZE_T_MAX) {
129 return PyErr_NoMemory();
130 }
131
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000132 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
133 if (new == NULL)
134 return NULL;
135
136 if (size == 0) {
137 new->ob_bytes = NULL;
138 alloc = 0;
139 }
140 else {
141 alloc = size + 1;
142 new->ob_bytes = PyMem_Malloc(alloc);
143 if (new->ob_bytes == NULL) {
144 Py_DECREF(new);
145 return PyErr_NoMemory();
146 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +0000147 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000148 memcpy(new->ob_bytes, bytes, size);
149 new->ob_bytes[size] = '\0'; /* Trailing null byte */
150 }
151 Py_SIZE(new) = size;
152 new->ob_alloc = alloc;
153 new->ob_exports = 0;
154
155 return (PyObject *)new;
156}
157
158Py_ssize_t
159PyByteArray_Size(PyObject *self)
160{
161 assert(self != NULL);
162 assert(PyByteArray_Check(self));
163
164 return PyByteArray_GET_SIZE(self);
165}
166
167char *
168PyByteArray_AsString(PyObject *self)
169{
170 assert(self != NULL);
171 assert(PyByteArray_Check(self));
172
173 return PyByteArray_AS_STRING(self);
174}
175
176int
177PyByteArray_Resize(PyObject *self, Py_ssize_t size)
178{
179 void *sval;
180 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
181
182 assert(self != NULL);
183 assert(PyByteArray_Check(self));
184 assert(size >= 0);
185
Antoine Pitrou5504e892008-12-06 21:27:53 +0000186 if (size == Py_SIZE(self)) {
187 return 0;
188 }
189 if (!_canresize((PyByteArrayObject *)self)) {
190 return -1;
191 }
192
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000193 if (size < alloc / 2) {
194 /* Major downsize; resize down to exact size */
195 alloc = size + 1;
196 }
197 else if (size < alloc) {
198 /* Within allocated size; quick exit */
199 Py_SIZE(self) = size;
200 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
201 return 0;
202 }
203 else if (size <= alloc * 1.125) {
204 /* Moderate upsize; overallocate similar to list_resize() */
205 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
206 }
207 else {
208 /* Major upsize; resize up to exact size */
209 alloc = size + 1;
210 }
211
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000212 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
213 if (sval == NULL) {
214 PyErr_NoMemory();
215 return -1;
216 }
217
218 ((PyByteArrayObject *)self)->ob_bytes = sval;
219 Py_SIZE(self) = size;
220 ((PyByteArrayObject *)self)->ob_alloc = alloc;
221 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
222
223 return 0;
224}
225
226PyObject *
227PyByteArray_Concat(PyObject *a, PyObject *b)
228{
229 Py_ssize_t size;
230 Py_buffer va, vb;
231 PyByteArrayObject *result = NULL;
232
233 va.len = -1;
234 vb.len = -1;
235 if (_getbuffer(a, &va) < 0 ||
236 _getbuffer(b, &vb) < 0) {
237 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
238 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
239 goto done;
240 }
241
242 size = va.len + vb.len;
243 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000244 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000245 goto done;
246 }
247
248 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
249 if (result != NULL) {
250 memcpy(result->ob_bytes, va.buf, va.len);
251 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
252 }
253
254 done:
255 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000256 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000257 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000258 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000259 return (PyObject *)result;
260}
261
262/* Functions stuffed into the type object */
263
264static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000265bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000266{
267 return Py_SIZE(self);
268}
269
270static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000271bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000272{
273 Py_ssize_t mysize;
274 Py_ssize_t size;
275 Py_buffer vo;
276
277 if (_getbuffer(other, &vo) < 0) {
278 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
279 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
280 return NULL;
281 }
282
283 mysize = Py_SIZE(self);
284 size = mysize + vo.len;
285 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000286 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000287 return PyErr_NoMemory();
288 }
289 if (size < self->ob_alloc) {
290 Py_SIZE(self) = size;
291 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
292 }
293 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000294 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000295 return NULL;
296 }
297 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000298 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000299 Py_INCREF(self);
300 return (PyObject *)self;
301}
302
303static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000304bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000305{
306 PyByteArrayObject *result;
307 Py_ssize_t mysize;
308 Py_ssize_t size;
309
310 if (count < 0)
311 count = 0;
312 mysize = Py_SIZE(self);
313 size = mysize * count;
314 if (count != 0 && size / count != mysize)
315 return PyErr_NoMemory();
316 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
317 if (result != NULL && size != 0) {
318 if (mysize == 1)
319 memset(result->ob_bytes, self->ob_bytes[0], size);
320 else {
321 Py_ssize_t i;
322 for (i = 0; i < count; i++)
323 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
324 }
325 }
326 return (PyObject *)result;
327}
328
329static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000330bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000331{
332 Py_ssize_t mysize;
333 Py_ssize_t size;
334
335 if (count < 0)
336 count = 0;
337 mysize = Py_SIZE(self);
338 size = mysize * count;
339 if (count != 0 && size / count != mysize)
340 return PyErr_NoMemory();
341 if (size < self->ob_alloc) {
342 Py_SIZE(self) = size;
343 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
344 }
345 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
346 return NULL;
347
348 if (mysize == 1)
349 memset(self->ob_bytes, self->ob_bytes[0], size);
350 else {
351 Py_ssize_t i;
352 for (i = 1; i < count; i++)
353 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
354 }
355
356 Py_INCREF(self);
357 return (PyObject *)self;
358}
359
360static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000361bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000362{
363 if (i < 0)
364 i += Py_SIZE(self);
365 if (i < 0 || i >= Py_SIZE(self)) {
366 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
367 return NULL;
368 }
369 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
370}
371
372static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000373bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000374{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000375 if (PyIndex_Check(index)) {
376 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000377
378 if (i == -1 && PyErr_Occurred())
379 return NULL;
380
381 if (i < 0)
382 i += PyByteArray_GET_SIZE(self);
383
384 if (i < 0 || i >= Py_SIZE(self)) {
385 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
386 return NULL;
387 }
388 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
389 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000390 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000391 Py_ssize_t start, stop, step, slicelength, cur, i;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000392 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000393 PyByteArray_GET_SIZE(self),
394 &start, &stop, &step, &slicelength) < 0) {
395 return NULL;
396 }
397
398 if (slicelength <= 0)
399 return PyByteArray_FromStringAndSize("", 0);
400 else if (step == 1) {
401 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
402 slicelength);
403 }
404 else {
405 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000406 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000407 PyObject *result;
408
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000409 result = PyByteArray_FromStringAndSize(NULL, slicelength);
410 if (result == NULL)
411 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000412
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000413 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000414 for (cur = start, i = 0; i < slicelength;
415 cur += step, i++) {
416 result_buf[i] = source_buf[cur];
417 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000418 return result;
419 }
420 }
421 else {
422 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
423 return NULL;
424 }
425}
426
427static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000428bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000429 PyObject *values)
430{
431 Py_ssize_t avail, needed;
432 void *bytes;
433 Py_buffer vbytes;
434 int res = 0;
435
436 vbytes.len = -1;
437 if (values == (PyObject *)self) {
438 /* Make a copy and call this function recursively */
439 int err;
440 values = PyByteArray_FromObject(values);
441 if (values == NULL)
442 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000443 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000444 Py_DECREF(values);
445 return err;
446 }
447 if (values == NULL) {
448 /* del b[lo:hi] */
449 bytes = NULL;
450 needed = 0;
451 }
452 else {
453 if (_getbuffer(values, &vbytes) < 0) {
454 PyErr_Format(PyExc_TypeError,
Georg Brandl3dbca812008-07-23 16:10:53 +0000455 "can't set bytearray slice from %.100s",
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000456 Py_TYPE(values)->tp_name);
457 return -1;
458 }
459 needed = vbytes.len;
460 bytes = vbytes.buf;
461 }
462
463 if (lo < 0)
464 lo = 0;
465 if (hi < lo)
466 hi = lo;
467 if (hi > Py_SIZE(self))
468 hi = Py_SIZE(self);
469
470 avail = hi - lo;
471 if (avail < 0)
472 lo = hi = avail = 0;
473
474 if (avail != needed) {
475 if (avail > needed) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000476 if (!_canresize(self)) {
477 res = -1;
478 goto finish;
479 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000480 /*
481 0 lo hi old_size
482 | |<----avail----->|<-----tomove------>|
483 | |<-needed->|<-----tomove------>|
484 0 lo new_hi new_size
485 */
486 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
487 Py_SIZE(self) - hi);
488 }
489 /* XXX(nnorwitz): need to verify this can't overflow! */
490 if (PyByteArray_Resize((PyObject *)self,
491 Py_SIZE(self) + needed - avail) < 0) {
492 res = -1;
493 goto finish;
494 }
495 if (avail < needed) {
496 /*
497 0 lo hi old_size
498 | |<-avail->|<-----tomove------>|
499 | |<----needed---->|<-----tomove------>|
500 0 lo new_hi new_size
501 */
502 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
503 Py_SIZE(self) - lo - needed);
504 }
505 }
506
507 if (needed > 0)
508 memcpy(self->ob_bytes + lo, bytes, needed);
509
510
511 finish:
512 if (vbytes.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000513 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000514 return res;
515}
516
517static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000518bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000519{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000520 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000521
522 if (i < 0)
523 i += Py_SIZE(self);
524
525 if (i < 0 || i >= Py_SIZE(self)) {
526 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
527 return -1;
528 }
529
530 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000531 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000532
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000533 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000534 return -1;
535
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000536 self->ob_bytes[i] = ival;
537 return 0;
538}
539
540static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000541bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000542{
543 Py_ssize_t start, stop, step, slicelen, needed;
544 char *bytes;
545
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000546 if (PyIndex_Check(index)) {
547 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000548
549 if (i == -1 && PyErr_Occurred())
550 return -1;
551
552 if (i < 0)
553 i += PyByteArray_GET_SIZE(self);
554
555 if (i < 0 || i >= Py_SIZE(self)) {
556 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
557 return -1;
558 }
559
560 if (values == NULL) {
561 /* Fall through to slice assignment */
562 start = i;
563 stop = i + 1;
564 step = 1;
565 slicelen = 1;
566 }
567 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000568 int ival;
569 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000570 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000571 self->ob_bytes[i] = (char)ival;
572 return 0;
573 }
574 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000575 else if (PySlice_Check(index)) {
576 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000577 PyByteArray_GET_SIZE(self),
578 &start, &stop, &step, &slicelen) < 0) {
579 return -1;
580 }
581 }
582 else {
583 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
584 return -1;
585 }
586
587 if (values == NULL) {
588 bytes = NULL;
589 needed = 0;
590 }
591 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
592 /* Make a copy an call this function recursively */
593 int err;
594 values = PyByteArray_FromObject(values);
595 if (values == NULL)
596 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000597 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000598 Py_DECREF(values);
599 return err;
600 }
601 else {
602 assert(PyByteArray_Check(values));
603 bytes = ((PyByteArrayObject *)values)->ob_bytes;
604 needed = Py_SIZE(values);
605 }
606 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
607 if ((step < 0 && start < stop) ||
608 (step > 0 && start > stop))
609 stop = start;
610 if (step == 1) {
611 if (slicelen != needed) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000612 if (!_canresize(self))
613 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000614 if (slicelen > needed) {
615 /*
616 0 start stop old_size
617 | |<---slicelen--->|<-----tomove------>|
618 | |<-needed->|<-----tomove------>|
619 0 lo new_hi new_size
620 */
621 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
622 Py_SIZE(self) - stop);
623 }
624 if (PyByteArray_Resize((PyObject *)self,
625 Py_SIZE(self) + needed - slicelen) < 0)
626 return -1;
627 if (slicelen < needed) {
628 /*
629 0 lo hi old_size
630 | |<-avail->|<-----tomove------>|
631 | |<----needed---->|<-----tomove------>|
632 0 lo new_hi new_size
633 */
634 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
635 Py_SIZE(self) - start - needed);
636 }
637 }
638
639 if (needed > 0)
640 memcpy(self->ob_bytes + start, bytes, needed);
641
642 return 0;
643 }
644 else {
645 if (needed == 0) {
646 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000647 size_t cur;
648 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000649
Antoine Pitrou5504e892008-12-06 21:27:53 +0000650 if (!_canresize(self))
651 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000652 if (step < 0) {
653 stop = start + 1;
654 start = stop + step * (slicelen - 1) - 1;
655 step = -step;
656 }
657 for (cur = start, i = 0;
658 i < slicelen; cur += step, i++) {
659 Py_ssize_t lim = step - 1;
660
Mark Dickinson66f575b2010-02-14 12:53:32 +0000661 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000662 lim = PyByteArray_GET_SIZE(self) - cur - 1;
663
664 memmove(self->ob_bytes + cur - i,
665 self->ob_bytes + cur + 1, lim);
666 }
667 /* Move the tail of the bytes, in one chunk */
668 cur = start + slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000669 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000670 memmove(self->ob_bytes + cur - slicelen,
671 self->ob_bytes + cur,
672 PyByteArray_GET_SIZE(self) - cur);
673 }
674 if (PyByteArray_Resize((PyObject *)self,
675 PyByteArray_GET_SIZE(self) - slicelen) < 0)
676 return -1;
677
678 return 0;
679 }
680 else {
681 /* Assign slice */
682 Py_ssize_t cur, i;
683
684 if (needed != slicelen) {
685 PyErr_Format(PyExc_ValueError,
686 "attempt to assign bytes of size %zd "
687 "to extended slice of size %zd",
688 needed, slicelen);
689 return -1;
690 }
691 for (cur = start, i = 0; i < slicelen; cur += step, i++)
692 self->ob_bytes[cur] = bytes[i];
693 return 0;
694 }
695 }
696}
697
698static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000699bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000700{
701 static char *kwlist[] = {"source", "encoding", "errors", 0};
702 PyObject *arg = NULL;
703 const char *encoding = NULL;
704 const char *errors = NULL;
705 Py_ssize_t count;
706 PyObject *it;
707 PyObject *(*iternext)(PyObject *);
708
709 if (Py_SIZE(self) != 0) {
710 /* Empty previous contents (yes, do this first of all!) */
711 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
712 return -1;
713 }
714
715 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000716 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000717 &arg, &encoding, &errors))
718 return -1;
719
720 /* Make a quick exit if no first argument */
721 if (arg == NULL) {
722 if (encoding != NULL || errors != NULL) {
723 PyErr_SetString(PyExc_TypeError,
724 "encoding or errors without sequence argument");
725 return -1;
726 }
727 return 0;
728 }
729
730 if (PyUnicode_Check(arg)) {
731 /* Encode via the codec registry */
732 PyObject *encoded, *new;
733 if (encoding == NULL) {
734 PyErr_SetString(PyExc_TypeError,
735 "string argument without an encoding");
736 return -1;
737 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000738 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000739 if (encoded == NULL)
740 return -1;
741 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000742 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000743 Py_DECREF(encoded);
744 if (new == NULL)
745 return -1;
746 Py_DECREF(new);
747 return 0;
748 }
749
750 /* If it's not unicode, there can't be encoding or errors */
751 if (encoding != NULL || errors != NULL) {
752 PyErr_SetString(PyExc_TypeError,
753 "encoding or errors without a string argument");
754 return -1;
755 }
756
757 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000758 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
759 if (count == -1 && PyErr_Occurred()) {
760 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000761 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000762 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000763 }
764 else if (count < 0) {
765 PyErr_SetString(PyExc_ValueError, "negative count");
766 return -1;
767 }
768 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000769 if (count > 0) {
770 if (PyByteArray_Resize((PyObject *)self, count))
771 return -1;
772 memset(self->ob_bytes, 0, count);
773 }
774 return 0;
775 }
776
777 /* Use the buffer API */
778 if (PyObject_CheckBuffer(arg)) {
779 Py_ssize_t size;
780 Py_buffer view;
781 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
782 return -1;
783 size = view.len;
784 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
785 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
786 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000787 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000788 return 0;
789 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000790 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000791 return -1;
792 }
793
794 /* XXX Optimize this if the arguments is a list, tuple */
795
796 /* Get the iterator */
797 it = PyObject_GetIter(arg);
798 if (it == NULL)
799 return -1;
800 iternext = *Py_TYPE(it)->tp_iternext;
801
802 /* Run the iterator to exhaustion */
803 for (;;) {
804 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000805 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000806
807 /* Get the next item */
808 item = iternext(it);
809 if (item == NULL) {
810 if (PyErr_Occurred()) {
811 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
812 goto error;
813 PyErr_Clear();
814 }
815 break;
816 }
817
818 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000819 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000820 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000821 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000822 goto error;
823
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000824 /* Append the byte */
825 if (Py_SIZE(self) < self->ob_alloc)
826 Py_SIZE(self)++;
827 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
828 goto error;
829 self->ob_bytes[Py_SIZE(self)-1] = value;
830 }
831
832 /* Clean up and return success */
833 Py_DECREF(it);
834 return 0;
835
836 error:
837 /* Error handling when it != NULL */
838 Py_DECREF(it);
839 return -1;
840}
841
842/* Mostly copied from string_repr, but without the
843 "smart quote" functionality. */
844static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000845bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000846{
847 static const char *hexdigits = "0123456789abcdef";
848 const char *quote_prefix = "bytearray(b";
849 const char *quote_postfix = ")";
850 Py_ssize_t length = Py_SIZE(self);
851 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000852 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000853 PyObject *v;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000854 if (length > (PY_SSIZE_T_MAX - 14) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000855 PyErr_SetString(PyExc_OverflowError,
856 "bytearray object is too large to make repr");
857 return NULL;
858 }
Mark Dickinson66f575b2010-02-14 12:53:32 +0000859 newsize = 14 + 4 * length;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000860 v = PyUnicode_FromUnicode(NULL, newsize);
861 if (v == NULL) {
862 return NULL;
863 }
864 else {
865 register Py_ssize_t i;
866 register Py_UNICODE c;
867 register Py_UNICODE *p;
868 int quote;
869
870 /* Figure out which quote to use; single is preferred */
871 quote = '\'';
872 {
873 char *test, *start;
874 start = PyByteArray_AS_STRING(self);
875 for (test = start; test < start+length; ++test) {
876 if (*test == '"') {
877 quote = '\''; /* back to single */
878 goto decided;
879 }
880 else if (*test == '\'')
881 quote = '"';
882 }
883 decided:
884 ;
885 }
886
887 p = PyUnicode_AS_UNICODE(v);
888 while (*quote_prefix)
889 *p++ = *quote_prefix++;
890 *p++ = quote;
891
892 for (i = 0; i < length; i++) {
893 /* There's at least enough room for a hex escape
894 and a closing quote. */
895 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5);
896 c = self->ob_bytes[i];
897 if (c == '\'' || c == '\\')
898 *p++ = '\\', *p++ = c;
899 else if (c == '\t')
900 *p++ = '\\', *p++ = 't';
901 else if (c == '\n')
902 *p++ = '\\', *p++ = 'n';
903 else if (c == '\r')
904 *p++ = '\\', *p++ = 'r';
905 else if (c == 0)
906 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
907 else if (c < ' ' || c >= 0x7f) {
908 *p++ = '\\';
909 *p++ = 'x';
910 *p++ = hexdigits[(c & 0xf0) >> 4];
911 *p++ = hexdigits[c & 0xf];
912 }
913 else
914 *p++ = c;
915 }
916 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1);
917 *p++ = quote;
918 while (*quote_postfix) {
919 *p++ = *quote_postfix++;
920 }
921 *p = '\0';
922 if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
923 Py_DECREF(v);
924 return NULL;
925 }
926 return v;
927 }
928}
929
930static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000931bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000932{
933 if (Py_BytesWarningFlag) {
934 if (PyErr_WarnEx(PyExc_BytesWarning,
935 "str() on a bytearray instance", 1))
936 return NULL;
937 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000938 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000939}
940
941static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000942bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000943{
944 Py_ssize_t self_size, other_size;
945 Py_buffer self_bytes, other_bytes;
946 PyObject *res;
947 Py_ssize_t minsize;
948 int cmp;
949
950 /* Bytes can be compared to anything that supports the (binary)
951 buffer API. Except that a comparison with Unicode is always an
952 error, even if the comparison is for equality. */
953 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
954 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +0000955 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000956 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +0000957 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000958 return NULL;
959 }
960
961 Py_INCREF(Py_NotImplemented);
962 return Py_NotImplemented;
963 }
964
965 self_size = _getbuffer(self, &self_bytes);
966 if (self_size < 0) {
967 PyErr_Clear();
968 Py_INCREF(Py_NotImplemented);
969 return Py_NotImplemented;
970 }
971
972 other_size = _getbuffer(other, &other_bytes);
973 if (other_size < 0) {
974 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +0000975 PyBuffer_Release(&self_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000976 Py_INCREF(Py_NotImplemented);
977 return Py_NotImplemented;
978 }
979
980 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
981 /* Shortcut: if the lengths differ, the objects differ */
982 cmp = (op == Py_NE);
983 }
984 else {
985 minsize = self_size;
986 if (other_size < minsize)
987 minsize = other_size;
988
989 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
990 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
991
992 if (cmp == 0) {
993 if (self_size < other_size)
994 cmp = -1;
995 else if (self_size > other_size)
996 cmp = 1;
997 }
998
999 switch (op) {
1000 case Py_LT: cmp = cmp < 0; break;
1001 case Py_LE: cmp = cmp <= 0; break;
1002 case Py_EQ: cmp = cmp == 0; break;
1003 case Py_NE: cmp = cmp != 0; break;
1004 case Py_GT: cmp = cmp > 0; break;
1005 case Py_GE: cmp = cmp >= 0; break;
1006 }
1007 }
1008
1009 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001010 PyBuffer_Release(&self_bytes);
1011 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001012 Py_INCREF(res);
1013 return res;
1014}
1015
1016static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001017bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001018{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001019 if (self->ob_exports > 0) {
1020 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001021 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001022 PyErr_Print();
1023 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001024 if (self->ob_bytes != 0) {
1025 PyMem_Free(self->ob_bytes);
1026 }
1027 Py_TYPE(self)->tp_free((PyObject *)self);
1028}
1029
1030
1031/* -------------------------------------------------------------------- */
1032/* Methods */
1033
1034#define STRINGLIB_CHAR char
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001035#define STRINGLIB_LEN PyByteArray_GET_SIZE
1036#define STRINGLIB_STR PyByteArray_AS_STRING
1037#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001038#define STRINGLIB_ISSPACE Py_ISSPACE
1039#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001040#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1041#define STRINGLIB_MUTABLE 1
1042
1043#include "stringlib/fastsearch.h"
1044#include "stringlib/count.h"
1045#include "stringlib/find.h"
1046#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001047#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001048#include "stringlib/ctype.h"
1049#include "stringlib/transmogrify.h"
1050
1051
1052/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1053were copied from the old char* style string object. */
1054
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001055/* helper macro to fixup start/end slice values */
1056#define ADJUST_INDICES(start, end, len) \
1057 if (end > len) \
1058 end = len; \
1059 else if (end < 0) { \
1060 end += len; \
1061 if (end < 0) \
1062 end = 0; \
1063 } \
1064 if (start < 0) { \
1065 start += len; \
1066 if (start < 0) \
1067 start = 0; \
1068 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001069
1070Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001071bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001072{
1073 PyObject *subobj;
1074 Py_buffer subbuf;
1075 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1076 Py_ssize_t res;
1077
1078 if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
1079 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1080 return -2;
1081 if (_getbuffer(subobj, &subbuf) < 0)
1082 return -2;
1083 if (dir > 0)
1084 res = stringlib_find_slice(
1085 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1086 subbuf.buf, subbuf.len, start, end);
1087 else
1088 res = stringlib_rfind_slice(
1089 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1090 subbuf.buf, subbuf.len, start, end);
Martin v. Löwis423be952008-08-13 15:53:07 +00001091 PyBuffer_Release(&subbuf);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001092 return res;
1093}
1094
1095PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001096"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001097\n\
1098Return the lowest index in B where subsection sub is found,\n\
1099such that sub is contained within s[start,end]. Optional\n\
1100arguments start and end are interpreted as in slice notation.\n\
1101\n\
1102Return -1 on failure.");
1103
1104static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001105bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001106{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001107 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001108 if (result == -2)
1109 return NULL;
1110 return PyLong_FromSsize_t(result);
1111}
1112
1113PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001114"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001115\n\
1116Return the number of non-overlapping occurrences of subsection sub in\n\
1117bytes B[start:end]. Optional arguments start and end are interpreted\n\
1118as in slice notation.");
1119
1120static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001121bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001122{
1123 PyObject *sub_obj;
1124 const char *str = PyByteArray_AS_STRING(self);
1125 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1126 Py_buffer vsub;
1127 PyObject *count_obj;
1128
1129 if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1130 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1131 return NULL;
1132
1133 if (_getbuffer(sub_obj, &vsub) < 0)
1134 return NULL;
1135
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001136 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001137
1138 count_obj = PyLong_FromSsize_t(
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001139 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001140 );
Martin v. Löwis423be952008-08-13 15:53:07 +00001141 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001142 return count_obj;
1143}
1144
1145
1146PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001147"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001148\n\
1149Like B.find() but raise ValueError when the subsection is not found.");
1150
1151static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001152bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001153{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001154 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001155 if (result == -2)
1156 return NULL;
1157 if (result == -1) {
1158 PyErr_SetString(PyExc_ValueError,
1159 "subsection not found");
1160 return NULL;
1161 }
1162 return PyLong_FromSsize_t(result);
1163}
1164
1165
1166PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001167"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001168\n\
1169Return the highest index in B where subsection sub is found,\n\
1170such that sub is contained within s[start,end]. Optional\n\
1171arguments start and end are interpreted as in slice notation.\n\
1172\n\
1173Return -1 on failure.");
1174
1175static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001176bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001177{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001178 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001179 if (result == -2)
1180 return NULL;
1181 return PyLong_FromSsize_t(result);
1182}
1183
1184
1185PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001186"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001187\n\
1188Like B.rfind() but raise ValueError when the subsection is not found.");
1189
1190static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001191bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001192{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001193 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001194 if (result == -2)
1195 return NULL;
1196 if (result == -1) {
1197 PyErr_SetString(PyExc_ValueError,
1198 "subsection not found");
1199 return NULL;
1200 }
1201 return PyLong_FromSsize_t(result);
1202}
1203
1204
1205static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001206bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001207{
1208 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1209 if (ival == -1 && PyErr_Occurred()) {
1210 Py_buffer varg;
1211 int pos;
1212 PyErr_Clear();
1213 if (_getbuffer(arg, &varg) < 0)
1214 return -1;
1215 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1216 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001217 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001218 return pos >= 0;
1219 }
1220 if (ival < 0 || ival >= 256) {
1221 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1222 return -1;
1223 }
1224
1225 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1226}
1227
1228
1229/* Matches the end (direction >= 0) or start (direction < 0) of self
1230 * against substr, using the start and end arguments. Returns
1231 * -1 on error, 0 if not found and 1 if found.
1232 */
1233Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001234_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001235 Py_ssize_t end, int direction)
1236{
1237 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1238 const char* str;
1239 Py_buffer vsubstr;
1240 int rv = 0;
1241
1242 str = PyByteArray_AS_STRING(self);
1243
1244 if (_getbuffer(substr, &vsubstr) < 0)
1245 return -1;
1246
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001247 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001248
1249 if (direction < 0) {
1250 /* startswith */
1251 if (start+vsubstr.len > len) {
1252 goto done;
1253 }
1254 } else {
1255 /* endswith */
1256 if (end-start < vsubstr.len || start > len) {
1257 goto done;
1258 }
1259
1260 if (end-vsubstr.len > start)
1261 start = end - vsubstr.len;
1262 }
1263 if (end-start >= vsubstr.len)
1264 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1265
1266done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001267 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001268 return rv;
1269}
1270
1271
1272PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001273"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001274\n\
1275Return True if B starts with the specified prefix, False otherwise.\n\
1276With optional start, test B beginning at that position.\n\
1277With optional end, stop comparing B at that position.\n\
1278prefix can also be a tuple of strings to try.");
1279
1280static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001281bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001282{
1283 Py_ssize_t start = 0;
1284 Py_ssize_t end = PY_SSIZE_T_MAX;
1285 PyObject *subobj;
1286 int result;
1287
1288 if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
1289 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1290 return NULL;
1291 if (PyTuple_Check(subobj)) {
1292 Py_ssize_t i;
1293 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001294 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001295 PyTuple_GET_ITEM(subobj, i),
1296 start, end, -1);
1297 if (result == -1)
1298 return NULL;
1299 else if (result) {
1300 Py_RETURN_TRUE;
1301 }
1302 }
1303 Py_RETURN_FALSE;
1304 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001305 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001306 if (result == -1)
1307 return NULL;
1308 else
1309 return PyBool_FromLong(result);
1310}
1311
1312PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001313"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001314\n\
1315Return True if B ends with the specified suffix, False otherwise.\n\
1316With optional start, test B beginning at that position.\n\
1317With optional end, stop comparing B at that position.\n\
1318suffix can also be a tuple of strings to try.");
1319
1320static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001321bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001322{
1323 Py_ssize_t start = 0;
1324 Py_ssize_t end = PY_SSIZE_T_MAX;
1325 PyObject *subobj;
1326 int result;
1327
1328 if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
1329 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1330 return NULL;
1331 if (PyTuple_Check(subobj)) {
1332 Py_ssize_t i;
1333 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001334 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001335 PyTuple_GET_ITEM(subobj, i),
1336 start, end, +1);
1337 if (result == -1)
1338 return NULL;
1339 else if (result) {
1340 Py_RETURN_TRUE;
1341 }
1342 }
1343 Py_RETURN_FALSE;
1344 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001345 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001346 if (result == -1)
1347 return NULL;
1348 else
1349 return PyBool_FromLong(result);
1350}
1351
1352
1353PyDoc_STRVAR(translate__doc__,
1354"B.translate(table[, deletechars]) -> bytearray\n\
1355\n\
1356Return a copy of B, where all characters occurring in the\n\
1357optional argument deletechars are removed, and the remaining\n\
1358characters have been mapped through the given translation\n\
1359table, which must be a bytes object of length 256.");
1360
1361static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001362bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001363{
1364 register char *input, *output;
1365 register const char *table;
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001366 register Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001367 PyObject *input_obj = (PyObject*)self;
1368 const char *output_start;
1369 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001370 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001371 int trans_table[256];
Georg Brandlccc47b62008-12-28 11:44:14 +00001372 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001373 Py_buffer vtable, vdel;
1374
1375 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1376 &tableobj, &delobj))
1377 return NULL;
1378
Georg Brandlccc47b62008-12-28 11:44:14 +00001379 if (tableobj == Py_None) {
1380 table = NULL;
1381 tableobj = NULL;
1382 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001383 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001384 } else {
1385 if (vtable.len != 256) {
1386 PyErr_SetString(PyExc_ValueError,
1387 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001388 PyBuffer_Release(&vtable);
1389 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001390 }
1391 table = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001392 }
1393
1394 if (delobj != NULL) {
1395 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandl953152f2009-07-22 12:03:59 +00001396 if (tableobj != NULL)
1397 PyBuffer_Release(&vtable);
1398 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001399 }
1400 }
1401 else {
1402 vdel.buf = NULL;
1403 vdel.len = 0;
1404 }
1405
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001406 inlen = PyByteArray_GET_SIZE(input_obj);
1407 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1408 if (result == NULL)
1409 goto done;
1410 output_start = output = PyByteArray_AsString(result);
1411 input = PyByteArray_AS_STRING(input_obj);
1412
Georg Brandlccc47b62008-12-28 11:44:14 +00001413 if (vdel.len == 0 && table != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001414 /* If no deletions are required, use faster code */
1415 for (i = inlen; --i >= 0; ) {
1416 c = Py_CHARMASK(*input++);
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001417 *output++ = table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001418 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001419 goto done;
1420 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001421
1422 if (table == NULL) {
1423 for (i = 0; i < 256; i++)
1424 trans_table[i] = Py_CHARMASK(i);
1425 } else {
1426 for (i = 0; i < 256; i++)
1427 trans_table[i] = Py_CHARMASK(table[i]);
1428 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001429
1430 for (i = 0; i < vdel.len; i++)
1431 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1432
1433 for (i = inlen; --i >= 0; ) {
1434 c = Py_CHARMASK(*input++);
1435 if (trans_table[c] != -1)
1436 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1437 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001438 }
1439 /* Fix the size of the resulting string */
1440 if (inlen > 0)
1441 PyByteArray_Resize(result, output - output_start);
1442
1443done:
Georg Brandlccc47b62008-12-28 11:44:14 +00001444 if (tableobj != NULL)
1445 PyBuffer_Release(&vtable);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001446 if (delobj != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001447 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001448 return result;
1449}
1450
1451
Georg Brandlabc38772009-04-12 15:51:51 +00001452static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001453bytearray_maketrans(PyObject *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001454{
1455 return _Py_bytes_maketrans(args);
1456}
1457
1458
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001459/* find and count characters and substrings */
1460
1461#define findchar(target, target_len, c) \
1462 ((char *)memchr((const void *)(target), c, target_len))
1463
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001464
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001465/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001466Py_LOCAL(PyByteArrayObject *)
1467return_self(PyByteArrayObject *self)
1468{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001469 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001470 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1471 PyByteArray_AS_STRING(self),
1472 PyByteArray_GET_SIZE(self));
1473}
1474
1475Py_LOCAL_INLINE(Py_ssize_t)
1476countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1477{
1478 Py_ssize_t count=0;
1479 const char *start=target;
1480 const char *end=target+target_len;
1481
1482 while ( (start=findchar(start, end-start, c)) != NULL ) {
1483 count++;
1484 if (count >= maxcount)
1485 break;
1486 start += 1;
1487 }
1488 return count;
1489}
1490
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001491
1492/* Algorithms for different cases of string replacement */
1493
1494/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1495Py_LOCAL(PyByteArrayObject *)
1496replace_interleave(PyByteArrayObject *self,
1497 const char *to_s, Py_ssize_t to_len,
1498 Py_ssize_t maxcount)
1499{
1500 char *self_s, *result_s;
1501 Py_ssize_t self_len, result_len;
1502 Py_ssize_t count, i, product;
1503 PyByteArrayObject *result;
1504
1505 self_len = PyByteArray_GET_SIZE(self);
1506
1507 /* 1 at the end plus 1 after every character */
1508 count = self_len+1;
1509 if (maxcount < count)
1510 count = maxcount;
1511
1512 /* Check for overflow */
1513 /* result_len = count * to_len + self_len; */
1514 product = count * to_len;
1515 if (product / to_len != count) {
1516 PyErr_SetString(PyExc_OverflowError,
1517 "replace string is too long");
1518 return NULL;
1519 }
1520 result_len = product + self_len;
1521 if (result_len < 0) {
1522 PyErr_SetString(PyExc_OverflowError,
1523 "replace string is too long");
1524 return NULL;
1525 }
1526
1527 if (! (result = (PyByteArrayObject *)
1528 PyByteArray_FromStringAndSize(NULL, result_len)) )
1529 return NULL;
1530
1531 self_s = PyByteArray_AS_STRING(self);
1532 result_s = PyByteArray_AS_STRING(result);
1533
1534 /* TODO: special case single character, which doesn't need memcpy */
1535
1536 /* Lay the first one down (guaranteed this will occur) */
1537 Py_MEMCPY(result_s, to_s, to_len);
1538 result_s += to_len;
1539 count -= 1;
1540
1541 for (i=0; i<count; i++) {
1542 *result_s++ = *self_s++;
1543 Py_MEMCPY(result_s, to_s, to_len);
1544 result_s += to_len;
1545 }
1546
1547 /* Copy the rest of the original string */
1548 Py_MEMCPY(result_s, self_s, self_len-i);
1549
1550 return result;
1551}
1552
1553/* Special case for deleting a single character */
1554/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1555Py_LOCAL(PyByteArrayObject *)
1556replace_delete_single_character(PyByteArrayObject *self,
1557 char from_c, Py_ssize_t maxcount)
1558{
1559 char *self_s, *result_s;
1560 char *start, *next, *end;
1561 Py_ssize_t self_len, result_len;
1562 Py_ssize_t count;
1563 PyByteArrayObject *result;
1564
1565 self_len = PyByteArray_GET_SIZE(self);
1566 self_s = PyByteArray_AS_STRING(self);
1567
1568 count = countchar(self_s, self_len, from_c, maxcount);
1569 if (count == 0) {
1570 return return_self(self);
1571 }
1572
1573 result_len = self_len - count; /* from_len == 1 */
1574 assert(result_len>=0);
1575
1576 if ( (result = (PyByteArrayObject *)
1577 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1578 return NULL;
1579 result_s = PyByteArray_AS_STRING(result);
1580
1581 start = self_s;
1582 end = self_s + self_len;
1583 while (count-- > 0) {
1584 next = findchar(start, end-start, from_c);
1585 if (next == NULL)
1586 break;
1587 Py_MEMCPY(result_s, start, next-start);
1588 result_s += (next-start);
1589 start = next+1;
1590 }
1591 Py_MEMCPY(result_s, start, end-start);
1592
1593 return result;
1594}
1595
1596/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1597
1598Py_LOCAL(PyByteArrayObject *)
1599replace_delete_substring(PyByteArrayObject *self,
1600 const char *from_s, Py_ssize_t from_len,
1601 Py_ssize_t maxcount)
1602{
1603 char *self_s, *result_s;
1604 char *start, *next, *end;
1605 Py_ssize_t self_len, result_len;
1606 Py_ssize_t count, offset;
1607 PyByteArrayObject *result;
1608
1609 self_len = PyByteArray_GET_SIZE(self);
1610 self_s = PyByteArray_AS_STRING(self);
1611
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001612 count = stringlib_count(self_s, self_len,
1613 from_s, from_len,
1614 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001615
1616 if (count == 0) {
1617 /* no matches */
1618 return return_self(self);
1619 }
1620
1621 result_len = self_len - (count * from_len);
1622 assert (result_len>=0);
1623
1624 if ( (result = (PyByteArrayObject *)
1625 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1626 return NULL;
1627
1628 result_s = PyByteArray_AS_STRING(result);
1629
1630 start = self_s;
1631 end = self_s + self_len;
1632 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001633 offset = stringlib_find(start, end-start,
1634 from_s, from_len,
1635 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001636 if (offset == -1)
1637 break;
1638 next = start + offset;
1639
1640 Py_MEMCPY(result_s, start, next-start);
1641
1642 result_s += (next-start);
1643 start = next+from_len;
1644 }
1645 Py_MEMCPY(result_s, start, end-start);
1646 return result;
1647}
1648
1649/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1650Py_LOCAL(PyByteArrayObject *)
1651replace_single_character_in_place(PyByteArrayObject *self,
1652 char from_c, char to_c,
1653 Py_ssize_t maxcount)
1654{
Antoine Pitroud1188562010-06-09 16:38:55 +00001655 char *self_s, *result_s, *start, *end, *next;
1656 Py_ssize_t self_len;
1657 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001658
Antoine Pitroud1188562010-06-09 16:38:55 +00001659 /* The result string will be the same size */
1660 self_s = PyByteArray_AS_STRING(self);
1661 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001662
Antoine Pitroud1188562010-06-09 16:38:55 +00001663 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001664
Antoine Pitroud1188562010-06-09 16:38:55 +00001665 if (next == NULL) {
1666 /* No matches; return the original bytes */
1667 return return_self(self);
1668 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001669
Antoine Pitroud1188562010-06-09 16:38:55 +00001670 /* Need to make a new bytes */
1671 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1672 if (result == NULL)
1673 return NULL;
1674 result_s = PyByteArray_AS_STRING(result);
1675 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001676
Antoine Pitroud1188562010-06-09 16:38:55 +00001677 /* change everything in-place, starting with this one */
1678 start = result_s + (next-self_s);
1679 *start = to_c;
1680 start++;
1681 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001682
Antoine Pitroud1188562010-06-09 16:38:55 +00001683 while (--maxcount > 0) {
1684 next = findchar(start, end-start, from_c);
1685 if (next == NULL)
1686 break;
1687 *next = to_c;
1688 start = next+1;
1689 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001690
Antoine Pitroud1188562010-06-09 16:38:55 +00001691 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001692}
1693
1694/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1695Py_LOCAL(PyByteArrayObject *)
1696replace_substring_in_place(PyByteArrayObject *self,
1697 const char *from_s, Py_ssize_t from_len,
1698 const char *to_s, Py_ssize_t to_len,
1699 Py_ssize_t maxcount)
1700{
1701 char *result_s, *start, *end;
1702 char *self_s;
1703 Py_ssize_t self_len, offset;
1704 PyByteArrayObject *result;
1705
1706 /* The result bytes will be the same size */
1707
1708 self_s = PyByteArray_AS_STRING(self);
1709 self_len = PyByteArray_GET_SIZE(self);
1710
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001711 offset = stringlib_find(self_s, self_len,
1712 from_s, from_len,
1713 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001714 if (offset == -1) {
1715 /* No matches; return the original bytes */
1716 return return_self(self);
1717 }
1718
1719 /* Need to make a new bytes */
1720 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1721 if (result == NULL)
1722 return NULL;
1723 result_s = PyByteArray_AS_STRING(result);
1724 Py_MEMCPY(result_s, self_s, self_len);
1725
1726 /* change everything in-place, starting with this one */
1727 start = result_s + offset;
1728 Py_MEMCPY(start, to_s, from_len);
1729 start += from_len;
1730 end = result_s + self_len;
1731
1732 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001733 offset = stringlib_find(start, end-start,
1734 from_s, from_len,
1735 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001736 if (offset==-1)
1737 break;
1738 Py_MEMCPY(start+offset, to_s, from_len);
1739 start += offset+from_len;
1740 }
1741
1742 return result;
1743}
1744
1745/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1746Py_LOCAL(PyByteArrayObject *)
1747replace_single_character(PyByteArrayObject *self,
1748 char from_c,
1749 const char *to_s, Py_ssize_t to_len,
1750 Py_ssize_t maxcount)
1751{
1752 char *self_s, *result_s;
1753 char *start, *next, *end;
1754 Py_ssize_t self_len, result_len;
1755 Py_ssize_t count, product;
1756 PyByteArrayObject *result;
1757
1758 self_s = PyByteArray_AS_STRING(self);
1759 self_len = PyByteArray_GET_SIZE(self);
1760
1761 count = countchar(self_s, self_len, from_c, maxcount);
1762 if (count == 0) {
1763 /* no matches, return unchanged */
1764 return return_self(self);
1765 }
1766
1767 /* use the difference between current and new, hence the "-1" */
1768 /* result_len = self_len + count * (to_len-1) */
1769 product = count * (to_len-1);
1770 if (product / (to_len-1) != count) {
1771 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1772 return NULL;
1773 }
1774 result_len = self_len + product;
1775 if (result_len < 0) {
1776 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1777 return NULL;
1778 }
1779
1780 if ( (result = (PyByteArrayObject *)
1781 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1782 return NULL;
1783 result_s = PyByteArray_AS_STRING(result);
1784
1785 start = self_s;
1786 end = self_s + self_len;
1787 while (count-- > 0) {
1788 next = findchar(start, end-start, from_c);
1789 if (next == NULL)
1790 break;
1791
1792 if (next == start) {
1793 /* replace with the 'to' */
1794 Py_MEMCPY(result_s, to_s, to_len);
1795 result_s += to_len;
1796 start += 1;
1797 } else {
1798 /* copy the unchanged old then the 'to' */
1799 Py_MEMCPY(result_s, start, next-start);
1800 result_s += (next-start);
1801 Py_MEMCPY(result_s, to_s, to_len);
1802 result_s += to_len;
1803 start = next+1;
1804 }
1805 }
1806 /* Copy the remainder of the remaining bytes */
1807 Py_MEMCPY(result_s, start, end-start);
1808
1809 return result;
1810}
1811
1812/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1813Py_LOCAL(PyByteArrayObject *)
1814replace_substring(PyByteArrayObject *self,
1815 const char *from_s, Py_ssize_t from_len,
1816 const char *to_s, Py_ssize_t to_len,
1817 Py_ssize_t maxcount)
1818{
1819 char *self_s, *result_s;
1820 char *start, *next, *end;
1821 Py_ssize_t self_len, result_len;
1822 Py_ssize_t count, offset, product;
1823 PyByteArrayObject *result;
1824
1825 self_s = PyByteArray_AS_STRING(self);
1826 self_len = PyByteArray_GET_SIZE(self);
1827
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001828 count = stringlib_count(self_s, self_len,
1829 from_s, from_len,
1830 maxcount);
1831
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001832 if (count == 0) {
1833 /* no matches, return unchanged */
1834 return return_self(self);
1835 }
1836
1837 /* Check for overflow */
1838 /* result_len = self_len + count * (to_len-from_len) */
1839 product = count * (to_len-from_len);
1840 if (product / (to_len-from_len) != count) {
1841 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1842 return NULL;
1843 }
1844 result_len = self_len + product;
1845 if (result_len < 0) {
1846 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1847 return NULL;
1848 }
1849
1850 if ( (result = (PyByteArrayObject *)
1851 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1852 return NULL;
1853 result_s = PyByteArray_AS_STRING(result);
1854
1855 start = self_s;
1856 end = self_s + self_len;
1857 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001858 offset = stringlib_find(start, end-start,
1859 from_s, from_len,
1860 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001861 if (offset == -1)
1862 break;
1863 next = start+offset;
1864 if (next == start) {
1865 /* replace with the 'to' */
1866 Py_MEMCPY(result_s, to_s, to_len);
1867 result_s += to_len;
1868 start += from_len;
1869 } else {
1870 /* copy the unchanged old then the 'to' */
1871 Py_MEMCPY(result_s, start, next-start);
1872 result_s += (next-start);
1873 Py_MEMCPY(result_s, to_s, to_len);
1874 result_s += to_len;
1875 start = next+from_len;
1876 }
1877 }
1878 /* Copy the remainder of the remaining bytes */
1879 Py_MEMCPY(result_s, start, end-start);
1880
1881 return result;
1882}
1883
1884
1885Py_LOCAL(PyByteArrayObject *)
1886replace(PyByteArrayObject *self,
1887 const char *from_s, Py_ssize_t from_len,
1888 const char *to_s, Py_ssize_t to_len,
1889 Py_ssize_t maxcount)
1890{
1891 if (maxcount < 0) {
1892 maxcount = PY_SSIZE_T_MAX;
1893 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1894 /* nothing to do; return the original bytes */
1895 return return_self(self);
1896 }
1897
1898 if (maxcount == 0 ||
1899 (from_len == 0 && to_len == 0)) {
1900 /* nothing to do; return the original bytes */
1901 return return_self(self);
1902 }
1903
1904 /* Handle zero-length special cases */
1905
1906 if (from_len == 0) {
1907 /* insert the 'to' bytes everywhere. */
1908 /* >>> "Python".replace("", ".") */
1909 /* '.P.y.t.h.o.n.' */
1910 return replace_interleave(self, to_s, to_len, maxcount);
1911 }
1912
1913 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1914 /* point for an empty self bytes to generate a non-empty bytes */
1915 /* Special case so the remaining code always gets a non-empty bytes */
1916 if (PyByteArray_GET_SIZE(self) == 0) {
1917 return return_self(self);
1918 }
1919
1920 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00001921 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001922 if (from_len == 1) {
1923 return replace_delete_single_character(
1924 self, from_s[0], maxcount);
1925 } else {
1926 return replace_delete_substring(self, from_s, from_len, maxcount);
1927 }
1928 }
1929
1930 /* Handle special case where both bytes have the same length */
1931
1932 if (from_len == to_len) {
1933 if (from_len == 1) {
1934 return replace_single_character_in_place(
1935 self,
1936 from_s[0],
1937 to_s[0],
1938 maxcount);
1939 } else {
1940 return replace_substring_in_place(
1941 self, from_s, from_len, to_s, to_len, maxcount);
1942 }
1943 }
1944
1945 /* Otherwise use the more generic algorithms */
1946 if (from_len == 1) {
1947 return replace_single_character(self, from_s[0],
1948 to_s, to_len, maxcount);
1949 } else {
1950 /* len('from')>=2, len('to')>=1 */
1951 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
1952 }
1953}
1954
1955
1956PyDoc_STRVAR(replace__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001957"B.replace(old, new[, count]) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001958\n\
1959Return a copy of B with all occurrences of subsection\n\
1960old replaced by new. If the optional argument count is\n\
1961given, only the first count occurrences are replaced.");
1962
1963static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001964bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001965{
1966 Py_ssize_t count = -1;
1967 PyObject *from, *to, *res;
1968 Py_buffer vfrom, vto;
1969
1970 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
1971 return NULL;
1972
1973 if (_getbuffer(from, &vfrom) < 0)
1974 return NULL;
1975 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +00001976 PyBuffer_Release(&vfrom);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001977 return NULL;
1978 }
1979
1980 res = (PyObject *)replace((PyByteArrayObject *) self,
1981 vfrom.buf, vfrom.len,
1982 vto.buf, vto.len, count);
1983
Martin v. Löwis423be952008-08-13 15:53:07 +00001984 PyBuffer_Release(&vfrom);
1985 PyBuffer_Release(&vto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001986 return res;
1987}
1988
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001989PyDoc_STRVAR(split__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001990"B.split([sep[, maxsplit]]) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001991\n\
1992Return a list of the sections in B, using sep as the delimiter.\n\
1993If sep is not given, B is split on ASCII whitespace characters\n\
1994(space, tab, return, newline, formfeed, vertical tab).\n\
1995If maxsplit is given, at most maxsplit splits are done.");
1996
1997static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001998bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001999{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002000 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2001 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002002 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002003 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002004 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002005
2006 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2007 return NULL;
2008 if (maxsplit < 0)
2009 maxsplit = PY_SSIZE_T_MAX;
2010
2011 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002012 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002013
2014 if (_getbuffer(subobj, &vsub) < 0)
2015 return NULL;
2016 sub = vsub.buf;
2017 n = vsub.len;
2018
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002019 list = stringlib_split(
2020 (PyObject*) self, s, len, sub, n, maxsplit
2021 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002022 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002023 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002024}
2025
2026PyDoc_STRVAR(partition__doc__,
2027"B.partition(sep) -> (head, sep, tail)\n\
2028\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002029Search for the separator sep in B, and return the part before it,\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002030the separator itself, and the part after it. If the separator is not\n\
2031found, returns B and two empty bytearray objects.");
2032
2033static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002034bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002035{
2036 PyObject *bytesep, *result;
2037
2038 bytesep = PyByteArray_FromObject(sep_obj);
2039 if (! bytesep)
2040 return NULL;
2041
2042 result = stringlib_partition(
2043 (PyObject*) self,
2044 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2045 bytesep,
2046 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2047 );
2048
2049 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002050 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002051}
2052
2053PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti5b2b2422010-01-25 11:58:28 +00002054"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002055\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002056Search for the separator sep in B, starting at the end of B,\n\
2057and return the part before it, the separator itself, and the\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002058part after it. If the separator is not found, returns two empty\n\
2059bytearray objects and B.");
2060
2061static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002062bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002063{
2064 PyObject *bytesep, *result;
2065
2066 bytesep = PyByteArray_FromObject(sep_obj);
2067 if (! bytesep)
2068 return NULL;
2069
2070 result = stringlib_rpartition(
2071 (PyObject*) self,
2072 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2073 bytesep,
2074 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2075 );
2076
2077 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002078 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002079}
2080
2081PyDoc_STRVAR(rsplit__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002082"B.rsplit(sep[, maxsplit]) -> list of bytearrays\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002083\n\
2084Return a list of the sections in B, using sep as the delimiter,\n\
2085starting at the end of B and working to the front.\n\
2086If sep is not given, B is split on ASCII whitespace characters\n\
2087(space, tab, return, newline, formfeed, vertical tab).\n\
2088If maxsplit is given, at most maxsplit splits are done.");
2089
2090static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002091bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002092{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002093 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2094 Py_ssize_t maxsplit = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002095 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002096 PyObject *list, *subobj = Py_None;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002097 Py_buffer vsub;
2098
2099 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2100 return NULL;
2101 if (maxsplit < 0)
2102 maxsplit = PY_SSIZE_T_MAX;
2103
2104 if (subobj == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002105 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002106
2107 if (_getbuffer(subobj, &vsub) < 0)
2108 return NULL;
2109 sub = vsub.buf;
2110 n = vsub.len;
2111
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002112 list = stringlib_rsplit(
2113 (PyObject*) self, s, len, sub, n, maxsplit
2114 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002115 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002116 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002117}
2118
2119PyDoc_STRVAR(reverse__doc__,
2120"B.reverse() -> None\n\
2121\n\
2122Reverse the order of the values in B in place.");
2123static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002124bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002125{
2126 char swap, *head, *tail;
2127 Py_ssize_t i, j, n = Py_SIZE(self);
2128
2129 j = n / 2;
2130 head = self->ob_bytes;
2131 tail = head + n - 1;
2132 for (i = 0; i < j; i++) {
2133 swap = *head;
2134 *head++ = *tail;
2135 *tail-- = swap;
2136 }
2137
2138 Py_RETURN_NONE;
2139}
2140
2141PyDoc_STRVAR(insert__doc__,
2142"B.insert(index, int) -> None\n\
2143\n\
2144Insert a single item into the bytearray before the given index.");
2145static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002146bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002147{
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002148 PyObject *value;
2149 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002150 Py_ssize_t where, n = Py_SIZE(self);
2151
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002152 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002153 return NULL;
2154
2155 if (n == PY_SSIZE_T_MAX) {
2156 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002157 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002158 return NULL;
2159 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002160 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002161 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002162 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2163 return NULL;
2164
2165 if (where < 0) {
2166 where += n;
2167 if (where < 0)
2168 where = 0;
2169 }
2170 if (where > n)
2171 where = n;
2172 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl9a54d7c2008-07-16 23:15:30 +00002173 self->ob_bytes[where] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002174
2175 Py_RETURN_NONE;
2176}
2177
2178PyDoc_STRVAR(append__doc__,
2179"B.append(int) -> None\n\
2180\n\
2181Append a single item to the end of B.");
2182static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002183bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002184{
2185 int value;
2186 Py_ssize_t n = Py_SIZE(self);
2187
2188 if (! _getbytevalue(arg, &value))
2189 return NULL;
2190 if (n == PY_SSIZE_T_MAX) {
2191 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002192 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002193 return NULL;
2194 }
2195 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2196 return NULL;
2197
2198 self->ob_bytes[n] = value;
2199
2200 Py_RETURN_NONE;
2201}
2202
2203PyDoc_STRVAR(extend__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002204"B.extend(iterable_of_ints) -> None\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002205\n\
2206Append all the elements from the iterator or sequence to the\n\
2207end of B.");
2208static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002209bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002210{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002211 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002212 Py_ssize_t buf_size = 0, len = 0;
2213 int value;
2214 char *buf;
2215
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002216 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002217 if (PyObject_CheckBuffer(arg)) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002218 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002219 return NULL;
2220
2221 Py_RETURN_NONE;
2222 }
2223
2224 it = PyObject_GetIter(arg);
2225 if (it == NULL)
2226 return NULL;
2227
2228 /* Try to determine the length of the argument. 32 is abitrary. */
2229 buf_size = _PyObject_LengthHint(arg, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002230 if (buf_size == -1) {
2231 Py_DECREF(it);
2232 return NULL;
2233 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002234
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002235 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2236 if (bytearray_obj == NULL)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002237 return NULL;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002238 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002239
2240 while ((item = PyIter_Next(it)) != NULL) {
2241 if (! _getbytevalue(item, &value)) {
2242 Py_DECREF(item);
2243 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002244 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002245 return NULL;
2246 }
2247 buf[len++] = value;
2248 Py_DECREF(item);
2249
2250 if (len >= buf_size) {
2251 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002252 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002253 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002254 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002255 return NULL;
2256 }
2257 /* Recompute the `buf' pointer, since the resizing operation may
2258 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002259 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002260 }
2261 }
2262 Py_DECREF(it);
2263
2264 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002265 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2266 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002267 return NULL;
2268 }
2269
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002270 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002271 return NULL;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002272 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002273
2274 Py_RETURN_NONE;
2275}
2276
2277PyDoc_STRVAR(pop__doc__,
2278"B.pop([index]) -> int\n\
2279\n\
2280Remove and return a single item from B. If no index\n\
Benjamin Petersondcf97b92008-07-02 17:30:14 +00002281argument is given, will pop the last value.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002282static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002283bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002284{
2285 int value;
2286 Py_ssize_t where = -1, n = Py_SIZE(self);
2287
2288 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2289 return NULL;
2290
2291 if (n == 0) {
2292 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002293 "cannot pop an empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002294 return NULL;
2295 }
2296 if (where < 0)
2297 where += Py_SIZE(self);
2298 if (where < 0 || where >= Py_SIZE(self)) {
2299 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2300 return NULL;
2301 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002302 if (!_canresize(self))
2303 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002304
2305 value = self->ob_bytes[where];
2306 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2307 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2308 return NULL;
2309
Mark Dickinson54a3db92009-09-06 10:19:23 +00002310 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002311}
2312
2313PyDoc_STRVAR(remove__doc__,
2314"B.remove(int) -> None\n\
2315\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002316Remove the first occurrence of a value in B.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002317static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002318bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002319{
2320 int value;
2321 Py_ssize_t where, n = Py_SIZE(self);
2322
2323 if (! _getbytevalue(arg, &value))
2324 return NULL;
2325
2326 for (where = 0; where < n; where++) {
2327 if (self->ob_bytes[where] == value)
2328 break;
2329 }
2330 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002331 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002332 return NULL;
2333 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002334 if (!_canresize(self))
2335 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002336
2337 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2338 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2339 return NULL;
2340
2341 Py_RETURN_NONE;
2342}
2343
2344/* XXX These two helpers could be optimized if argsize == 1 */
2345
2346static Py_ssize_t
2347lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2348 void *argptr, Py_ssize_t argsize)
2349{
2350 Py_ssize_t i = 0;
2351 while (i < mysize && memchr(argptr, myptr[i], argsize))
2352 i++;
2353 return i;
2354}
2355
2356static Py_ssize_t
2357rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2358 void *argptr, Py_ssize_t argsize)
2359{
2360 Py_ssize_t i = mysize - 1;
2361 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2362 i--;
2363 return i + 1;
2364}
2365
2366PyDoc_STRVAR(strip__doc__,
2367"B.strip([bytes]) -> bytearray\n\
2368\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002369Strip leading and trailing bytes contained in the argument\n\
2370and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002371If the argument is omitted, strip ASCII whitespace.");
2372static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002373bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002374{
2375 Py_ssize_t left, right, mysize, argsize;
2376 void *myptr, *argptr;
2377 PyObject *arg = Py_None;
2378 Py_buffer varg;
2379 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2380 return NULL;
2381 if (arg == Py_None) {
2382 argptr = "\t\n\r\f\v ";
2383 argsize = 6;
2384 }
2385 else {
2386 if (_getbuffer(arg, &varg) < 0)
2387 return NULL;
2388 argptr = varg.buf;
2389 argsize = varg.len;
2390 }
2391 myptr = self->ob_bytes;
2392 mysize = Py_SIZE(self);
2393 left = lstrip_helper(myptr, mysize, argptr, argsize);
2394 if (left == mysize)
2395 right = left;
2396 else
2397 right = rstrip_helper(myptr, mysize, argptr, argsize);
2398 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002399 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002400 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2401}
2402
2403PyDoc_STRVAR(lstrip__doc__,
2404"B.lstrip([bytes]) -> bytearray\n\
2405\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002406Strip leading bytes contained in the argument\n\
2407and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002408If the argument is omitted, strip leading ASCII whitespace.");
2409static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002410bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002411{
2412 Py_ssize_t left, right, mysize, argsize;
2413 void *myptr, *argptr;
2414 PyObject *arg = Py_None;
2415 Py_buffer varg;
2416 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2417 return NULL;
2418 if (arg == Py_None) {
2419 argptr = "\t\n\r\f\v ";
2420 argsize = 6;
2421 }
2422 else {
2423 if (_getbuffer(arg, &varg) < 0)
2424 return NULL;
2425 argptr = varg.buf;
2426 argsize = varg.len;
2427 }
2428 myptr = self->ob_bytes;
2429 mysize = Py_SIZE(self);
2430 left = lstrip_helper(myptr, mysize, argptr, argsize);
2431 right = mysize;
2432 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002433 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002434 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2435}
2436
2437PyDoc_STRVAR(rstrip__doc__,
2438"B.rstrip([bytes]) -> bytearray\n\
2439\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002440Strip trailing bytes contained in the argument\n\
2441and return the result as a new bytearray.\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002442If the argument is omitted, strip trailing ASCII whitespace.");
2443static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002444bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002445{
2446 Py_ssize_t left, right, mysize, argsize;
2447 void *myptr, *argptr;
2448 PyObject *arg = Py_None;
2449 Py_buffer varg;
2450 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2451 return NULL;
2452 if (arg == Py_None) {
2453 argptr = "\t\n\r\f\v ";
2454 argsize = 6;
2455 }
2456 else {
2457 if (_getbuffer(arg, &varg) < 0)
2458 return NULL;
2459 argptr = varg.buf;
2460 argsize = varg.len;
2461 }
2462 myptr = self->ob_bytes;
2463 mysize = Py_SIZE(self);
2464 left = 0;
2465 right = rstrip_helper(myptr, mysize, argptr, argsize);
2466 if (arg != Py_None)
Martin v. Löwis423be952008-08-13 15:53:07 +00002467 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002468 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2469}
2470
2471PyDoc_STRVAR(decode_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002472"B.decode([encoding[, errors]]) -> str\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002473\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002474Decode B using the codec registered for encoding. encoding defaults\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002475to the default encoding. errors may be given to set a different error\n\
2476handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2477a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2478as well as any other name registered with codecs.register_error that is\n\
2479able to handle UnicodeDecodeErrors.");
2480
2481static PyObject *
Benjamin Peterson308d6372009-09-18 21:42:35 +00002482bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002483{
2484 const char *encoding = NULL;
2485 const char *errors = NULL;
Benjamin Peterson308d6372009-09-18 21:42:35 +00002486 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002487
Benjamin Peterson308d6372009-09-18 21:42:35 +00002488 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002489 return NULL;
2490 if (encoding == NULL)
2491 encoding = PyUnicode_GetDefaultEncoding();
Marc-André Lemburgb2750b52008-06-06 12:18:17 +00002492 return PyUnicode_FromEncodedObject(self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002493}
2494
2495PyDoc_STRVAR(alloc_doc,
2496"B.__alloc__() -> int\n\
2497\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002498Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002499
2500static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002501bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002502{
2503 return PyLong_FromSsize_t(self->ob_alloc);
2504}
2505
2506PyDoc_STRVAR(join_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002507"B.join(iterable_of_bytes) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002508\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002509Concatenate any number of bytes/bytearray objects, with B\n\
2510in between each pair, and return the result as a new bytearray.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002511
2512static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002513bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002514{
2515 PyObject *seq;
2516 Py_ssize_t mysize = Py_SIZE(self);
2517 Py_ssize_t i;
2518 Py_ssize_t n;
2519 PyObject **items;
2520 Py_ssize_t totalsize = 0;
2521 PyObject *result;
2522 char *dest;
2523
2524 seq = PySequence_Fast(it, "can only join an iterable");
2525 if (seq == NULL)
2526 return NULL;
2527 n = PySequence_Fast_GET_SIZE(seq);
2528 items = PySequence_Fast_ITEMS(seq);
2529
2530 /* Compute the total size, and check that they are all bytes */
2531 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2532 for (i = 0; i < n; i++) {
2533 PyObject *obj = items[i];
2534 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2535 PyErr_Format(PyExc_TypeError,
2536 "can only join an iterable of bytes "
2537 "(item %ld has type '%.100s')",
2538 /* XXX %ld isn't right on Win64 */
2539 (long)i, Py_TYPE(obj)->tp_name);
2540 goto error;
2541 }
2542 if (i > 0)
2543 totalsize += mysize;
2544 totalsize += Py_SIZE(obj);
2545 if (totalsize < 0) {
2546 PyErr_NoMemory();
2547 goto error;
2548 }
2549 }
2550
2551 /* Allocate the result, and copy the bytes */
2552 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2553 if (result == NULL)
2554 goto error;
2555 dest = PyByteArray_AS_STRING(result);
2556 for (i = 0; i < n; i++) {
2557 PyObject *obj = items[i];
2558 Py_ssize_t size = Py_SIZE(obj);
2559 char *buf;
2560 if (PyByteArray_Check(obj))
2561 buf = PyByteArray_AS_STRING(obj);
2562 else
2563 buf = PyBytes_AS_STRING(obj);
2564 if (i) {
2565 memcpy(dest, self->ob_bytes, mysize);
2566 dest += mysize;
2567 }
2568 memcpy(dest, buf, size);
2569 dest += size;
2570 }
2571
2572 /* Done */
2573 Py_DECREF(seq);
2574 return result;
2575
2576 /* Error handling */
2577 error:
2578 Py_DECREF(seq);
2579 return NULL;
2580}
2581
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002582PyDoc_STRVAR(splitlines__doc__,
2583"B.splitlines([keepends]) -> list of lines\n\
2584\n\
2585Return a list of the lines in B, breaking at line boundaries.\n\
2586Line breaks are not included in the resulting list unless keepends\n\
2587is given and true.");
2588
2589static PyObject*
2590bytearray_splitlines(PyObject *self, PyObject *args)
2591{
2592 int keepends = 0;
2593
2594 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2595 return NULL;
2596
2597 return stringlib_splitlines(
2598 (PyObject*) self, PyByteArray_AS_STRING(self),
2599 PyByteArray_GET_SIZE(self), keepends
2600 );
2601}
2602
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002603PyDoc_STRVAR(fromhex_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002604"bytearray.fromhex(string) -> bytearray (static method)\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002605\n\
2606Create a bytearray object from a string of hexadecimal numbers.\n\
2607Spaces between two numbers are accepted.\n\
2608Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2609
2610static int
2611hex_digit_to_int(Py_UNICODE c)
2612{
2613 if (c >= 128)
2614 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002615 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002616 return c - '0';
2617 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002618 if (Py_ISUPPER(c))
2619 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002620 if (c >= 'a' && c <= 'f')
2621 return c - 'a' + 10;
2622 }
2623 return -1;
2624}
2625
2626static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002627bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002628{
2629 PyObject *newbytes, *hexobj;
2630 char *buf;
2631 Py_UNICODE *hex;
2632 Py_ssize_t hexlen, byteslen, i, j;
2633 int top, bot;
2634
2635 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
2636 return NULL;
2637 assert(PyUnicode_Check(hexobj));
2638 hexlen = PyUnicode_GET_SIZE(hexobj);
2639 hex = PyUnicode_AS_UNICODE(hexobj);
2640 byteslen = hexlen/2; /* This overestimates if there are spaces */
2641 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2642 if (!newbytes)
2643 return NULL;
2644 buf = PyByteArray_AS_STRING(newbytes);
2645 for (i = j = 0; i < hexlen; i += 2) {
2646 /* skip over spaces in the input */
2647 while (hex[i] == ' ')
2648 i++;
2649 if (i >= hexlen)
2650 break;
2651 top = hex_digit_to_int(hex[i]);
2652 bot = hex_digit_to_int(hex[i+1]);
2653 if (top == -1 || bot == -1) {
2654 PyErr_Format(PyExc_ValueError,
2655 "non-hexadecimal number found in "
2656 "fromhex() arg at position %zd", i);
2657 goto error;
2658 }
2659 buf[j++] = (top << 4) + bot;
2660 }
2661 if (PyByteArray_Resize(newbytes, j) < 0)
2662 goto error;
2663 return newbytes;
2664
2665 error:
2666 Py_DECREF(newbytes);
2667 return NULL;
2668}
2669
2670PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2671
2672static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002673bytearray_reduce(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002674{
2675 PyObject *latin1, *dict;
2676 if (self->ob_bytes)
2677 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2678 Py_SIZE(self), NULL);
2679 else
2680 latin1 = PyUnicode_FromString("");
2681
2682 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2683 if (dict == NULL) {
2684 PyErr_Clear();
2685 dict = Py_None;
2686 Py_INCREF(dict);
2687 }
2688
2689 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2690}
2691
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002692PyDoc_STRVAR(sizeof_doc,
2693"B.__sizeof__() -> int\n\
2694 \n\
2695Returns the size of B in memory, in bytes");
2696static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002697bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002698{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002699 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002700
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002701 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2702 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002703}
2704
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002705static PySequenceMethods bytearray_as_sequence = {
2706 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002707 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002708 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2709 (ssizeargfunc)bytearray_getitem, /* sq_item */
2710 0, /* sq_slice */
2711 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2712 0, /* sq_ass_slice */
2713 (objobjproc)bytearray_contains, /* sq_contains */
2714 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2715 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002716};
2717
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002718static PyMappingMethods bytearray_as_mapping = {
2719 (lenfunc)bytearray_length,
2720 (binaryfunc)bytearray_subscript,
2721 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002722};
2723
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002724static PyBufferProcs bytearray_as_buffer = {
2725 (getbufferproc)bytearray_getbuffer,
2726 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002727};
2728
2729static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002730bytearray_methods[] = {
2731 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2732 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2733 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2734 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002735 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2736 _Py_capitalize__doc__},
2737 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002738 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Peterson308d6372009-09-18 21:42:35 +00002739 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002740 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002741 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2742 expandtabs__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002743 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2744 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2745 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002746 fromhex_doc},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002747 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2748 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002749 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2750 _Py_isalnum__doc__},
2751 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2752 _Py_isalpha__doc__},
2753 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2754 _Py_isdigit__doc__},
2755 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2756 _Py_islower__doc__},
2757 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2758 _Py_isspace__doc__},
2759 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2760 _Py_istitle__doc__},
2761 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2762 _Py_isupper__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002763 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002764 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2765 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002766 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2767 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
Georg Brandlabc38772009-04-12 15:51:51 +00002768 _Py_maketrans__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002769 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2770 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2771 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2772 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2773 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2774 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2775 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002776 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002777 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2778 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2779 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2780 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002781 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002782 splitlines__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002783 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002784 startswith__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002785 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002786 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2787 _Py_swapcase__doc__},
2788 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002789 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002790 translate__doc__},
2791 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2792 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2793 {NULL}
2794};
2795
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002796PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002797"bytearray(iterable_of_ints) -> bytearray\n\
2798bytearray(string, encoding[, errors]) -> bytearray\n\
2799bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray\n\
2800bytearray(memory_view) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002801\n\
2802Construct an mutable bytearray object from:\n\
2803 - an iterable yielding integers in range(256)\n\
2804 - a text string encoded using the specified encoding\n\
2805 - a bytes or a bytearray object\n\
2806 - any object implementing the buffer API.\n\
2807\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002808bytearray(int) -> bytearray\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002809\n\
2810Construct a zero-initialized bytearray of the given length.");
2811
2812
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002813static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002814
2815PyTypeObject PyByteArray_Type = {
2816 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2817 "bytearray",
2818 sizeof(PyByteArrayObject),
2819 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002820 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002821 0, /* tp_print */
2822 0, /* tp_getattr */
2823 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002824 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002825 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002826 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002827 &bytearray_as_sequence, /* tp_as_sequence */
2828 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002829 0, /* tp_hash */
2830 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002831 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002832 PyObject_GenericGetAttr, /* tp_getattro */
2833 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002834 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002835 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002836 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002837 0, /* tp_traverse */
2838 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002839 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002840 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002841 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002842 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002843 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002844 0, /* tp_members */
2845 0, /* tp_getset */
2846 0, /* tp_base */
2847 0, /* tp_dict */
2848 0, /* tp_descr_get */
2849 0, /* tp_descr_set */
2850 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002851 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002852 PyType_GenericAlloc, /* tp_alloc */
2853 PyType_GenericNew, /* tp_new */
2854 PyObject_Del, /* tp_free */
2855};
2856
2857/*********************** Bytes Iterator ****************************/
2858
2859typedef struct {
2860 PyObject_HEAD
2861 Py_ssize_t it_index;
2862 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2863} bytesiterobject;
2864
2865static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002866bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002867{
2868 _PyObject_GC_UNTRACK(it);
2869 Py_XDECREF(it->it_seq);
2870 PyObject_GC_Del(it);
2871}
2872
2873static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002874bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002875{
2876 Py_VISIT(it->it_seq);
2877 return 0;
2878}
2879
2880static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002881bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002882{
2883 PyByteArrayObject *seq;
2884 PyObject *item;
2885
2886 assert(it != NULL);
2887 seq = it->it_seq;
2888 if (seq == NULL)
2889 return NULL;
2890 assert(PyByteArray_Check(seq));
2891
2892 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2893 item = PyLong_FromLong(
2894 (unsigned char)seq->ob_bytes[it->it_index]);
2895 if (item != NULL)
2896 ++it->it_index;
2897 return item;
2898 }
2899
2900 Py_DECREF(seq);
2901 it->it_seq = NULL;
2902 return NULL;
2903}
2904
2905static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002906bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002907{
2908 Py_ssize_t len = 0;
2909 if (it->it_seq)
2910 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2911 return PyLong_FromSsize_t(len);
2912}
2913
2914PyDoc_STRVAR(length_hint_doc,
2915 "Private method returning an estimate of len(list(it)).");
2916
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002917static PyMethodDef bytearrayiter_methods[] = {
2918 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002919 length_hint_doc},
2920 {NULL, NULL} /* sentinel */
2921};
2922
2923PyTypeObject PyByteArrayIter_Type = {
2924 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2925 "bytearray_iterator", /* tp_name */
2926 sizeof(bytesiterobject), /* tp_basicsize */
2927 0, /* tp_itemsize */
2928 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002929 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002930 0, /* tp_print */
2931 0, /* tp_getattr */
2932 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002933 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002934 0, /* tp_repr */
2935 0, /* tp_as_number */
2936 0, /* tp_as_sequence */
2937 0, /* tp_as_mapping */
2938 0, /* tp_hash */
2939 0, /* tp_call */
2940 0, /* tp_str */
2941 PyObject_GenericGetAttr, /* tp_getattro */
2942 0, /* tp_setattro */
2943 0, /* tp_as_buffer */
2944 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2945 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002946 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002947 0, /* tp_clear */
2948 0, /* tp_richcompare */
2949 0, /* tp_weaklistoffset */
2950 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002951 (iternextfunc)bytearrayiter_next, /* tp_iternext */
2952 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002953 0,
2954};
2955
2956static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002957bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002958{
2959 bytesiterobject *it;
2960
2961 if (!PyByteArray_Check(seq)) {
2962 PyErr_BadInternalCall();
2963 return NULL;
2964 }
2965 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
2966 if (it == NULL)
2967 return NULL;
2968 it->it_index = 0;
2969 Py_INCREF(seq);
2970 it->it_seq = (PyByteArrayObject *)seq;
2971 _PyObject_GC_TRACK(it);
2972 return (PyObject *)it;
2973}