blob: 04c25061ef52d21676297a1e007a107d451934b4 [file] [log] [blame]
Christian Heimes44720832008-05-26 13:01:01 +00001/* PyBytes (bytearray) implementation */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
5#include "structmember.h"
6#include "bytes_methods.h"
7
Antoine Pitroue80a6a42010-01-17 12:26:20 +00008char _PyByteArray_empty_string[] = "";
Christian Heimes44720832008-05-26 13:01:01 +00009
10void
11PyByteArray_Fini(void)
12{
Christian Heimes44720832008-05-26 13:01:01 +000013}
14
15int
16PyByteArray_Init(void)
17{
Christian Heimes44720832008-05-26 13:01:01 +000018 return 1;
19}
20
21/* end nullbytes support */
22
23/* Helpers */
24
25static int
26_getbytevalue(PyObject* arg, int *value)
27{
28 long face_value;
29
Georg Brandl3e483f62008-07-16 22:57:41 +000030 if (PyBytes_CheckExact(arg)) {
Christian Heimes44720832008-05-26 13:01:01 +000031 if (Py_SIZE(arg) != 1) {
32 PyErr_SetString(PyExc_ValueError, "string must be of size 1");
33 return 0;
34 }
Georg Brandl3e483f62008-07-16 22:57:41 +000035 *value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
36 return 1;
37 }
38 else if (PyInt_Check(arg) || PyLong_Check(arg)) {
39 face_value = PyLong_AsLong(arg);
Christian Heimes44720832008-05-26 13:01:01 +000040 }
41 else {
Georg Brandl3e483f62008-07-16 22:57:41 +000042 PyObject *index = PyNumber_Index(arg);
43 if (index == NULL) {
44 PyErr_Format(PyExc_TypeError,
45 "an integer or string of size 1 is required");
46 return 0;
47 }
48 face_value = PyLong_AsLong(index);
49 Py_DECREF(index);
50 }
Georg Brandl3e483f62008-07-16 22:57:41 +000051
52 if (face_value < 0 || face_value >= 256) {
Georg Brandl3238a3e2008-07-16 23:17:46 +000053 /* this includes the OverflowError in case the long is too large */
Georg Brandl3e483f62008-07-16 22:57:41 +000054 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Christian Heimes44720832008-05-26 13:01:01 +000055 return 0;
56 }
57
58 *value = face_value;
59 return 1;
60}
61
62static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000063bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000064{
65 if ( index != 0 ) {
66 PyErr_SetString(PyExc_SystemError,
67 "accessing non-existent bytes segment");
68 return -1;
69 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +000070 *ptr = (void *)PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +000071 return Py_SIZE(self);
72}
73
74static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000075bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000076{
77 if ( index != 0 ) {
78 PyErr_SetString(PyExc_SystemError,
79 "accessing non-existent bytes segment");
80 return -1;
81 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +000082 *ptr = (void *)PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +000083 return Py_SIZE(self);
84}
85
86static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000087bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
Christian Heimes44720832008-05-26 13:01:01 +000088{
89 if ( lenp )
90 *lenp = Py_SIZE(self);
91 return 1;
92}
93
94static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000095bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000096{
97 if ( index != 0 ) {
98 PyErr_SetString(PyExc_SystemError,
99 "accessing non-existent bytes segment");
100 return -1;
101 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000102 *ptr = PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +0000103 return Py_SIZE(self);
104}
105
106static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000107bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes44720832008-05-26 13:01:01 +0000108{
Antoine Pitrou619f16e2010-06-09 16:24:00 +0000109 int ret;
110 void *ptr;
111 if (view == NULL) {
112 obj->ob_exports++;
113 return 0;
114 }
115 ptr = (void *) PyByteArray_AS_STRING(obj);
116 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
117 if (ret >= 0) {
118 obj->ob_exports++;
119 }
120 return ret;
Christian Heimes44720832008-05-26 13:01:01 +0000121}
122
123static void
Benjamin Petersond6720012009-04-18 15:31:34 +0000124bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes44720832008-05-26 13:01:01 +0000125{
Antoine Pitrou619f16e2010-06-09 16:24:00 +0000126 obj->ob_exports--;
Christian Heimes44720832008-05-26 13:01:01 +0000127}
128
129static Py_ssize_t
130_getbuffer(PyObject *obj, Py_buffer *view)
131{
132 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
133
134 if (buffer == NULL || buffer->bf_getbuffer == NULL)
135 {
136 PyErr_Format(PyExc_TypeError,
137 "Type %.100s doesn't support the buffer API",
138 Py_TYPE(obj)->tp_name);
139 return -1;
140 }
141
142 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
143 return -1;
144 return view->len;
145}
146
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000147static int
148_canresize(PyByteArrayObject *self)
149{
150 if (self->ob_exports > 0) {
151 PyErr_SetString(PyExc_BufferError,
152 "Existing exports of data: object cannot be re-sized");
153 return 0;
154 }
155 return 1;
156}
157
Christian Heimes44720832008-05-26 13:01:01 +0000158/* Direct API functions */
159
160PyObject *
161PyByteArray_FromObject(PyObject *input)
162{
163 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
164 input, NULL);
165}
166
Serhiy Storchaka107f3cc2017-10-29 12:25:38 +0200167static PyObject *
168_PyByteArray_FromBufferObject(PyObject *obj)
169{
170 PyObject *result;
171 Py_buffer view;
172
173 if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
174 return NULL;
175 }
176 result = PyByteArray_FromStringAndSize(NULL, view.len);
177 if (result != NULL &&
178 PyBuffer_ToContiguous(PyByteArray_AS_STRING(result),
179 &view, view.len, 'C') < 0)
180 {
181 Py_CLEAR(result);
182 }
183 PyBuffer_Release(&view);
184 return result;
185}
186
Christian Heimes44720832008-05-26 13:01:01 +0000187PyObject *
188PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
189{
190 PyByteArrayObject *new;
191 Py_ssize_t alloc;
192
193 if (size < 0) {
194 PyErr_SetString(PyExc_SystemError,
195 "Negative size passed to PyByteArray_FromStringAndSize");
196 return NULL;
197 }
198
199 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
200 if (new == NULL)
201 return NULL;
202
203 if (size == 0) {
204 new->ob_bytes = NULL;
205 alloc = 0;
206 }
207 else {
208 alloc = size + 1;
209 new->ob_bytes = PyMem_Malloc(alloc);
210 if (new->ob_bytes == NULL) {
211 Py_DECREF(new);
212 return PyErr_NoMemory();
213 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000214 if (bytes != NULL && size > 0)
Christian Heimes44720832008-05-26 13:01:01 +0000215 memcpy(new->ob_bytes, bytes, size);
216 new->ob_bytes[size] = '\0'; /* Trailing null byte */
217 }
218 Py_SIZE(new) = size;
219 new->ob_alloc = alloc;
220 new->ob_exports = 0;
221
222 return (PyObject *)new;
223}
224
225Py_ssize_t
226PyByteArray_Size(PyObject *self)
227{
228 assert(self != NULL);
229 assert(PyByteArray_Check(self));
230
231 return PyByteArray_GET_SIZE(self);
232}
233
234char *
235PyByteArray_AsString(PyObject *self)
236{
237 assert(self != NULL);
238 assert(PyByteArray_Check(self));
239
240 return PyByteArray_AS_STRING(self);
241}
242
243int
244PyByteArray_Resize(PyObject *self, Py_ssize_t size)
245{
246 void *sval;
247 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
248
249 assert(self != NULL);
250 assert(PyByteArray_Check(self));
251 assert(size >= 0);
252
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000253 if (size == Py_SIZE(self)) {
254 return 0;
255 }
256 if (!_canresize((PyByteArrayObject *)self)) {
257 return -1;
258 }
259
Christian Heimes44720832008-05-26 13:01:01 +0000260 if (size < alloc / 2) {
261 /* Major downsize; resize down to exact size */
262 alloc = size + 1;
263 }
264 else if (size < alloc) {
265 /* Within allocated size; quick exit */
266 Py_SIZE(self) = size;
267 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
268 return 0;
269 }
270 else if (size <= alloc * 1.125) {
271 /* Moderate upsize; overallocate similar to list_resize() */
272 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
273 }
274 else {
275 /* Major upsize; resize up to exact size */
276 alloc = size + 1;
277 }
278
Christian Heimes44720832008-05-26 13:01:01 +0000279 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
280 if (sval == NULL) {
281 PyErr_NoMemory();
282 return -1;
283 }
284
285 ((PyByteArrayObject *)self)->ob_bytes = sval;
286 Py_SIZE(self) = size;
287 ((PyByteArrayObject *)self)->ob_alloc = alloc;
288 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
289
290 return 0;
291}
292
293PyObject *
294PyByteArray_Concat(PyObject *a, PyObject *b)
295{
Christian Heimes44720832008-05-26 13:01:01 +0000296 Py_buffer va, vb;
297 PyByteArrayObject *result = NULL;
298
299 va.len = -1;
300 vb.len = -1;
301 if (_getbuffer(a, &va) < 0 ||
302 _getbuffer(b, &vb) < 0) {
303 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
304 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
305 goto done;
306 }
307
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300308 if (va.len > PY_SSIZE_T_MAX - vb.len) {
309 PyErr_NoMemory();
310 goto done;
Christian Heimes44720832008-05-26 13:01:01 +0000311 }
312
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300313 result = (PyByteArrayObject *) \
314 PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
Christian Heimes44720832008-05-26 13:01:01 +0000315 if (result != NULL) {
316 memcpy(result->ob_bytes, va.buf, va.len);
317 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
318 }
319
320 done:
321 if (va.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000322 PyBuffer_Release(&va);
Christian Heimes44720832008-05-26 13:01:01 +0000323 if (vb.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000324 PyBuffer_Release(&vb);
Christian Heimes44720832008-05-26 13:01:01 +0000325 return (PyObject *)result;
326}
327
328/* Functions stuffed into the type object */
329
330static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +0000331bytearray_length(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000332{
333 return Py_SIZE(self);
334}
335
336static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000337bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes44720832008-05-26 13:01:01 +0000338{
339 Py_ssize_t mysize;
340 Py_ssize_t size;
341 Py_buffer vo;
342
343 if (_getbuffer(other, &vo) < 0) {
344 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
345 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
346 return NULL;
347 }
348
349 mysize = Py_SIZE(self);
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300350 if (mysize > PY_SSIZE_T_MAX - vo.len) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000351 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000352 return PyErr_NoMemory();
353 }
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300354 size = mysize + vo.len;
Christian Heimes44720832008-05-26 13:01:01 +0000355 if (size < self->ob_alloc) {
356 Py_SIZE(self) = size;
357 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
358 }
359 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000360 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000361 return NULL;
362 }
363 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000364 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000365 Py_INCREF(self);
366 return (PyObject *)self;
367}
368
369static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000370bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000371{
372 PyByteArrayObject *result;
373 Py_ssize_t mysize;
374 Py_ssize_t size;
375
376 if (count < 0)
377 count = 0;
378 mysize = Py_SIZE(self);
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300379 if (count != 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes44720832008-05-26 13:01:01 +0000380 return PyErr_NoMemory();
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300381 size = mysize * count;
Christian Heimes44720832008-05-26 13:01:01 +0000382 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
383 if (result != NULL && size != 0) {
384 if (mysize == 1)
385 memset(result->ob_bytes, self->ob_bytes[0], size);
386 else {
387 Py_ssize_t i;
388 for (i = 0; i < count; i++)
389 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
390 }
391 }
392 return (PyObject *)result;
393}
394
395static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000396bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000397{
398 Py_ssize_t mysize;
399 Py_ssize_t size;
400
401 if (count < 0)
402 count = 0;
403 mysize = Py_SIZE(self);
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300404 if (count != 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes44720832008-05-26 13:01:01 +0000405 return PyErr_NoMemory();
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300406 size = mysize * count;
Christian Heimes44720832008-05-26 13:01:01 +0000407 if (size < self->ob_alloc) {
408 Py_SIZE(self) = size;
409 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
410 }
411 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
412 return NULL;
413
414 if (mysize == 1)
415 memset(self->ob_bytes, self->ob_bytes[0], size);
416 else {
417 Py_ssize_t i;
418 for (i = 1; i < count; i++)
419 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
420 }
421
422 Py_INCREF(self);
423 return (PyObject *)self;
424}
425
426static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000427bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes44720832008-05-26 13:01:01 +0000428{
429 if (i < 0)
430 i += Py_SIZE(self);
431 if (i < 0 || i >= Py_SIZE(self)) {
432 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
433 return NULL;
434 }
435 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
436}
437
438static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000439bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes44720832008-05-26 13:01:01 +0000440{
Georg Brandl3e483f62008-07-16 22:57:41 +0000441 if (PyIndex_Check(index)) {
442 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000443
444 if (i == -1 && PyErr_Occurred())
445 return NULL;
446
447 if (i < 0)
448 i += PyByteArray_GET_SIZE(self);
449
450 if (i < 0 || i >= Py_SIZE(self)) {
451 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
452 return NULL;
453 }
454 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
455 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000456 else if (PySlice_Check(index)) {
Christian Heimes44720832008-05-26 13:01:01 +0000457 Py_ssize_t start, stop, step, slicelength, cur, i;
Serhiy Storchaka5e793212017-04-15 20:11:12 +0300458 if (_PySlice_Unpack(index, &start, &stop, &step) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +0000459 return NULL;
460 }
Serhiy Storchakae41390a2017-04-08 11:48:57 +0300461 slicelength = _PySlice_AdjustIndices(PyByteArray_GET_SIZE(self),
462 &start, &stop, step);
Christian Heimes44720832008-05-26 13:01:01 +0000463
464 if (slicelength <= 0)
465 return PyByteArray_FromStringAndSize("", 0);
466 else if (step == 1) {
467 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
468 slicelength);
469 }
470 else {
471 char *source_buf = PyByteArray_AS_STRING(self);
472 char *result_buf = (char *)PyMem_Malloc(slicelength);
473 PyObject *result;
474
475 if (result_buf == NULL)
476 return PyErr_NoMemory();
477
478 for (cur = start, i = 0; i < slicelength;
479 cur += step, i++) {
480 result_buf[i] = source_buf[cur];
481 }
482 result = PyByteArray_FromStringAndSize(result_buf, slicelength);
483 PyMem_Free(result_buf);
484 return result;
485 }
486 }
487 else {
488 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
489 return NULL;
490 }
491}
492
493static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000494bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes44720832008-05-26 13:01:01 +0000495 PyObject *values)
496{
497 Py_ssize_t avail, needed;
498 void *bytes;
499 Py_buffer vbytes;
500 int res = 0;
501
502 vbytes.len = -1;
503 if (values == (PyObject *)self) {
504 /* Make a copy and call this function recursively */
505 int err;
Serhiy Storchaka107f3cc2017-10-29 12:25:38 +0200506 values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values),
507 PyByteArray_GET_SIZE(values));
Christian Heimes44720832008-05-26 13:01:01 +0000508 if (values == NULL)
509 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000510 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes44720832008-05-26 13:01:01 +0000511 Py_DECREF(values);
512 return err;
513 }
514 if (values == NULL) {
515 /* del b[lo:hi] */
516 bytes = NULL;
517 needed = 0;
518 }
519 else {
520 if (_getbuffer(values, &vbytes) < 0) {
521 PyErr_Format(PyExc_TypeError,
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000522 "can't set bytearray slice from %.100s",
Christian Heimes44720832008-05-26 13:01:01 +0000523 Py_TYPE(values)->tp_name);
524 return -1;
525 }
526 needed = vbytes.len;
527 bytes = vbytes.buf;
528 }
529
530 if (lo < 0)
531 lo = 0;
532 if (hi < lo)
533 hi = lo;
534 if (hi > Py_SIZE(self))
535 hi = Py_SIZE(self);
536
537 avail = hi - lo;
538 if (avail < 0)
539 lo = hi = avail = 0;
540
541 if (avail != needed) {
542 if (avail > needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000543 if (!_canresize(self)) {
544 res = -1;
545 goto finish;
546 }
Christian Heimes44720832008-05-26 13:01:01 +0000547 /*
548 0 lo hi old_size
549 | |<----avail----->|<-----tomove------>|
550 | |<-needed->|<-----tomove------>|
551 0 lo new_hi new_size
552 */
553 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
554 Py_SIZE(self) - hi);
555 }
556 /* XXX(nnorwitz): need to verify this can't overflow! */
557 if (PyByteArray_Resize((PyObject *)self,
558 Py_SIZE(self) + needed - avail) < 0) {
559 res = -1;
560 goto finish;
561 }
562 if (avail < needed) {
563 /*
564 0 lo hi old_size
565 | |<-avail->|<-----tomove------>|
566 | |<----needed---->|<-----tomove------>|
567 0 lo new_hi new_size
568 */
569 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
570 Py_SIZE(self) - lo - needed);
571 }
572 }
573
574 if (needed > 0)
575 memcpy(self->ob_bytes + lo, bytes, needed);
576
577
578 finish:
579 if (vbytes.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000580 PyBuffer_Release(&vbytes);
Christian Heimes44720832008-05-26 13:01:01 +0000581 return res;
582}
583
584static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000585bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes44720832008-05-26 13:01:01 +0000586{
587 int ival;
588
589 if (i < 0)
590 i += Py_SIZE(self);
591
592 if (i < 0 || i >= Py_SIZE(self)) {
593 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
594 return -1;
595 }
596
597 if (value == NULL)
Benjamin Petersond6720012009-04-18 15:31:34 +0000598 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes44720832008-05-26 13:01:01 +0000599
600 if (!_getbytevalue(value, &ival))
601 return -1;
602
603 self->ob_bytes[i] = ival;
604 return 0;
605}
606
607static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000608bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes44720832008-05-26 13:01:01 +0000609{
610 Py_ssize_t start, stop, step, slicelen, needed;
611 char *bytes;
612
Georg Brandl3e483f62008-07-16 22:57:41 +0000613 if (PyIndex_Check(index)) {
614 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000615
616 if (i == -1 && PyErr_Occurred())
617 return -1;
618
619 if (i < 0)
620 i += PyByteArray_GET_SIZE(self);
621
622 if (i < 0 || i >= Py_SIZE(self)) {
623 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
624 return -1;
625 }
626
627 if (values == NULL) {
628 /* Fall through to slice assignment */
629 start = i;
630 stop = i + 1;
631 step = 1;
632 slicelen = 1;
633 }
634 else {
Georg Brandl3e483f62008-07-16 22:57:41 +0000635 int ival;
636 if (!_getbytevalue(values, &ival))
Christian Heimes44720832008-05-26 13:01:01 +0000637 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000638 self->ob_bytes[i] = (char)ival;
639 return 0;
640 }
641 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000642 else if (PySlice_Check(index)) {
Serhiy Storchaka5e793212017-04-15 20:11:12 +0300643 if (_PySlice_Unpack(index, &start, &stop, &step) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +0000644 return -1;
645 }
Serhiy Storchakae41390a2017-04-08 11:48:57 +0300646 slicelen = _PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start,
647 &stop, step);
Christian Heimes44720832008-05-26 13:01:01 +0000648 }
649 else {
650 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
651 return -1;
652 }
653
654 if (values == NULL) {
655 bytes = NULL;
656 needed = 0;
657 }
658 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes146a5fe2012-11-03 23:07:59 +0100659 int err;
Ezio Melotti67dc4a82012-11-03 21:10:45 +0200660 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
661 PyErr_SetString(PyExc_TypeError,
662 "can assign only bytes, buffers, or iterables "
663 "of ints in range(0, 256)");
664 return -1;
665 }
Georg Brandl28dadd92011-02-25 10:50:32 +0000666 /* Make a copy and call this function recursively */
Christian Heimes44720832008-05-26 13:01:01 +0000667 values = PyByteArray_FromObject(values);
668 if (values == NULL)
669 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000670 err = bytearray_ass_subscript(self, index, values);
Christian Heimes44720832008-05-26 13:01:01 +0000671 Py_DECREF(values);
672 return err;
673 }
674 else {
675 assert(PyByteArray_Check(values));
676 bytes = ((PyByteArrayObject *)values)->ob_bytes;
677 needed = Py_SIZE(values);
678 }
679 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
680 if ((step < 0 && start < stop) ||
681 (step > 0 && start > stop))
682 stop = start;
683 if (step == 1) {
684 if (slicelen != needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000685 if (!_canresize(self))
686 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000687 if (slicelen > needed) {
688 /*
689 0 start stop old_size
690 | |<---slicelen--->|<-----tomove------>|
691 | |<-needed->|<-----tomove------>|
692 0 lo new_hi new_size
693 */
694 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
695 Py_SIZE(self) - stop);
696 }
697 if (PyByteArray_Resize((PyObject *)self,
698 Py_SIZE(self) + needed - slicelen) < 0)
699 return -1;
700 if (slicelen < needed) {
701 /*
702 0 lo hi old_size
703 | |<-avail->|<-----tomove------>|
704 | |<----needed---->|<-----tomove------>|
705 0 lo new_hi new_size
706 */
707 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
708 Py_SIZE(self) - start - needed);
709 }
710 }
711
712 if (needed > 0)
713 memcpy(self->ob_bytes + start, bytes, needed);
714
715 return 0;
716 }
717 else {
718 if (needed == 0) {
719 /* Delete slice */
Mark Dickinson36ecd672010-01-29 17:11:39 +0000720 size_t cur;
721 Py_ssize_t i;
Christian Heimes44720832008-05-26 13:01:01 +0000722
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000723 if (!_canresize(self))
724 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000725 if (step < 0) {
726 stop = start + 1;
727 start = stop + step * (slicelen - 1) - 1;
728 step = -step;
729 }
730 for (cur = start, i = 0;
731 i < slicelen; cur += step, i++) {
732 Py_ssize_t lim = step - 1;
733
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000734 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes44720832008-05-26 13:01:01 +0000735 lim = PyByteArray_GET_SIZE(self) - cur - 1;
736
737 memmove(self->ob_bytes + cur - i,
738 self->ob_bytes + cur + 1, lim);
739 }
740 /* Move the tail of the bytes, in one chunk */
741 cur = start + slicelen*step;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000742 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Christian Heimes44720832008-05-26 13:01:01 +0000743 memmove(self->ob_bytes + cur - slicelen,
744 self->ob_bytes + cur,
745 PyByteArray_GET_SIZE(self) - cur);
746 }
747 if (PyByteArray_Resize((PyObject *)self,
748 PyByteArray_GET_SIZE(self) - slicelen) < 0)
749 return -1;
750
751 return 0;
752 }
753 else {
754 /* Assign slice */
755 Py_ssize_t cur, i;
756
757 if (needed != slicelen) {
758 PyErr_Format(PyExc_ValueError,
759 "attempt to assign bytes of size %zd "
760 "to extended slice of size %zd",
761 needed, slicelen);
762 return -1;
763 }
764 for (cur = start, i = 0; i < slicelen; cur += step, i++)
765 self->ob_bytes[cur] = bytes[i];
766 return 0;
767 }
768 }
769}
770
771static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000772bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes44720832008-05-26 13:01:01 +0000773{
774 static char *kwlist[] = {"source", "encoding", "errors", 0};
775 PyObject *arg = NULL;
776 const char *encoding = NULL;
777 const char *errors = NULL;
778 Py_ssize_t count;
779 PyObject *it;
780 PyObject *(*iternext)(PyObject *);
781
782 if (Py_SIZE(self) != 0) {
783 /* Empty previous contents (yes, do this first of all!) */
784 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
785 return -1;
786 }
787
788 /* Parse arguments */
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000789 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes44720832008-05-26 13:01:01 +0000790 &arg, &encoding, &errors))
791 return -1;
792
793 /* Make a quick exit if no first argument */
794 if (arg == NULL) {
795 if (encoding != NULL || errors != NULL) {
796 PyErr_SetString(PyExc_TypeError,
797 "encoding or errors without sequence argument");
798 return -1;
799 }
800 return 0;
801 }
802
803 if (PyBytes_Check(arg)) {
804 PyObject *new, *encoded;
805 if (encoding != NULL) {
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300806 encoded = _PyCodec_EncodeText(arg, encoding, errors);
Christian Heimes44720832008-05-26 13:01:01 +0000807 if (encoded == NULL)
808 return -1;
809 assert(PyBytes_Check(encoded));
810 }
811 else {
812 encoded = arg;
813 Py_INCREF(arg);
814 }
Benjamin Petersond6720012009-04-18 15:31:34 +0000815 new = bytearray_iconcat(self, arg);
Christian Heimes44720832008-05-26 13:01:01 +0000816 Py_DECREF(encoded);
817 if (new == NULL)
818 return -1;
819 Py_DECREF(new);
820 return 0;
821 }
822
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000823#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +0000824 if (PyUnicode_Check(arg)) {
825 /* Encode via the codec registry */
826 PyObject *encoded, *new;
827 if (encoding == NULL) {
828 PyErr_SetString(PyExc_TypeError,
829 "unicode argument without an encoding");
830 return -1;
831 }
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300832 encoded = _PyCodec_EncodeText(arg, encoding, errors);
Christian Heimes44720832008-05-26 13:01:01 +0000833 if (encoded == NULL)
834 return -1;
835 assert(PyBytes_Check(encoded));
Benjamin Petersond6720012009-04-18 15:31:34 +0000836 new = bytearray_iconcat(self, encoded);
Christian Heimes44720832008-05-26 13:01:01 +0000837 Py_DECREF(encoded);
838 if (new == NULL)
839 return -1;
840 Py_DECREF(new);
841 return 0;
842 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000843#endif
Christian Heimes44720832008-05-26 13:01:01 +0000844
845 /* If it's not unicode, there can't be encoding or errors */
846 if (encoding != NULL || errors != NULL) {
847 PyErr_SetString(PyExc_TypeError,
848 "encoding or errors without a string argument");
849 return -1;
850 }
851
852 /* Is it an int? */
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000853 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
854 if (count == -1 && PyErr_Occurred()) {
855 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes44720832008-05-26 13:01:01 +0000856 return -1;
Benjamin Petersonae530c22010-04-16 22:52:44 +0000857 PyErr_Clear();
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000858 }
859 else if (count < 0) {
860 PyErr_SetString(PyExc_ValueError, "negative count");
861 return -1;
862 }
863 else {
Christian Heimes44720832008-05-26 13:01:01 +0000864 if (count > 0) {
865 if (PyByteArray_Resize((PyObject *)self, count))
866 return -1;
867 memset(self->ob_bytes, 0, count);
868 }
869 return 0;
870 }
871
872 /* Use the buffer API */
873 if (PyObject_CheckBuffer(arg)) {
874 Py_ssize_t size;
875 Py_buffer view;
876 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
877 return -1;
878 size = view.len;
879 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
880 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
881 goto fail;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000882 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000883 return 0;
884 fail:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000885 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000886 return -1;
887 }
888
889 /* XXX Optimize this if the arguments is a list, tuple */
890
891 /* Get the iterator */
892 it = PyObject_GetIter(arg);
893 if (it == NULL)
894 return -1;
895 iternext = *Py_TYPE(it)->tp_iternext;
896
897 /* Run the iterator to exhaustion */
898 for (;;) {
899 PyObject *item;
Georg Brandl3e758462008-07-16 23:10:05 +0000900 int rc, value;
Christian Heimes44720832008-05-26 13:01:01 +0000901
902 /* Get the next item */
903 item = iternext(it);
904 if (item == NULL) {
905 if (PyErr_Occurred()) {
906 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
907 goto error;
908 PyErr_Clear();
909 }
910 break;
911 }
912
913 /* Interpret it as an int (__index__) */
Georg Brandl3e758462008-07-16 23:10:05 +0000914 rc = _getbytevalue(item, &value);
Christian Heimes44720832008-05-26 13:01:01 +0000915 Py_DECREF(item);
Georg Brandl3e758462008-07-16 23:10:05 +0000916 if (!rc)
Christian Heimes44720832008-05-26 13:01:01 +0000917 goto error;
918
Christian Heimes44720832008-05-26 13:01:01 +0000919 /* Append the byte */
Serhiy Storchakaab766352015-06-29 21:13:54 +0300920 if (Py_SIZE(self) + 1 < self->ob_alloc) {
Christian Heimes44720832008-05-26 13:01:01 +0000921 Py_SIZE(self)++;
Serhiy Storchakaab766352015-06-29 21:13:54 +0300922 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
923 }
Christian Heimes44720832008-05-26 13:01:01 +0000924 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
925 goto error;
926 self->ob_bytes[Py_SIZE(self)-1] = value;
927 }
928
929 /* Clean up and return success */
930 Py_DECREF(it);
931 return 0;
932
933 error:
934 /* Error handling when it != NULL */
935 Py_DECREF(it);
936 return -1;
937}
938
939/* Mostly copied from string_repr, but without the
940 "smart quote" functionality. */
941static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000942bytearray_repr(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000943{
944 static const char *hexdigits = "0123456789abcdef";
945 const char *quote_prefix = "bytearray(b";
946 const char *quote_postfix = ")";
947 Py_ssize_t length = Py_SIZE(self);
948 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000949 size_t newsize;
Christian Heimes44720832008-05-26 13:01:01 +0000950 PyObject *v;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000951 if (length > (PY_SSIZE_T_MAX - 14) / 4) {
Christian Heimes44720832008-05-26 13:01:01 +0000952 PyErr_SetString(PyExc_OverflowError,
953 "bytearray object is too large to make repr");
954 return NULL;
955 }
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000956 newsize = 14 + 4 * length;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000957 v = PyString_FromStringAndSize(NULL, newsize);
Christian Heimes44720832008-05-26 13:01:01 +0000958 if (v == NULL) {
959 return NULL;
960 }
961 else {
962 register Py_ssize_t i;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000963 register char c;
964 register char *p;
Christian Heimes44720832008-05-26 13:01:01 +0000965 int quote;
966
967 /* Figure out which quote to use; single is preferred */
968 quote = '\'';
969 {
970 char *test, *start;
971 start = PyByteArray_AS_STRING(self);
972 for (test = start; test < start+length; ++test) {
973 if (*test == '"') {
974 quote = '\''; /* back to single */
975 goto decided;
976 }
977 else if (*test == '\'')
978 quote = '"';
979 }
980 decided:
981 ;
982 }
983
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000984 p = PyString_AS_STRING(v);
Christian Heimes44720832008-05-26 13:01:01 +0000985 while (*quote_prefix)
986 *p++ = *quote_prefix++;
987 *p++ = quote;
988
989 for (i = 0; i < length; i++) {
990 /* There's at least enough room for a hex escape
991 and a closing quote. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000992 assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
Christian Heimes44720832008-05-26 13:01:01 +0000993 c = self->ob_bytes[i];
994 if (c == '\'' || c == '\\')
995 *p++ = '\\', *p++ = c;
996 else if (c == '\t')
997 *p++ = '\\', *p++ = 't';
998 else if (c == '\n')
999 *p++ = '\\', *p++ = 'n';
1000 else if (c == '\r')
1001 *p++ = '\\', *p++ = 'r';
1002 else if (c == 0)
1003 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
1004 else if (c < ' ' || c >= 0x7f) {
1005 *p++ = '\\';
1006 *p++ = 'x';
1007 *p++ = hexdigits[(c & 0xf0) >> 4];
1008 *p++ = hexdigits[c & 0xf];
1009 }
1010 else
1011 *p++ = c;
1012 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001013 assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
Christian Heimes44720832008-05-26 13:01:01 +00001014 *p++ = quote;
1015 while (*quote_postfix) {
1016 *p++ = *quote_postfix++;
1017 }
1018 *p = '\0';
Kristján Valur Jónssonbe580f22014-04-25 09:51:21 +00001019 /* v is cleared on error */
1020 (void)_PyString_Resize(&v, (p - PyString_AS_STRING(v)));
Christian Heimes44720832008-05-26 13:01:01 +00001021 return v;
1022 }
1023}
1024
1025static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001026bytearray_str(PyObject *op)
Christian Heimes44720832008-05-26 13:01:01 +00001027{
1028#if 0
1029 if (Py_BytesWarningFlag) {
1030 if (PyErr_WarnEx(PyExc_BytesWarning,
1031 "str() on a bytearray instance", 1))
1032 return NULL;
1033 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001034 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes44720832008-05-26 13:01:01 +00001035#endif
1036 return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
1037}
1038
1039static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001040bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes44720832008-05-26 13:01:01 +00001041{
1042 Py_ssize_t self_size, other_size;
1043 Py_buffer self_bytes, other_bytes;
1044 PyObject *res;
1045 Py_ssize_t minsize;
Serhiy Storchaka5127ed72015-05-30 17:45:12 +03001046 int cmp, rc;
Christian Heimes44720832008-05-26 13:01:01 +00001047
1048 /* Bytes can be compared to anything that supports the (binary)
1049 buffer API. Except that a comparison with Unicode is always an
1050 error, even if the comparison is for equality. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001051#ifdef Py_USING_UNICODE
Serhiy Storchaka5127ed72015-05-30 17:45:12 +03001052 rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type);
1053 if (!rc)
1054 rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type);
1055 if (rc < 0)
1056 return NULL;
1057 if (rc) {
Christian Heimes44720832008-05-26 13:01:01 +00001058 if (Py_BytesWarningFlag && op == Py_EQ) {
1059 if (PyErr_WarnEx(PyExc_BytesWarning,
Ezio Melottid2342082010-01-14 11:34:10 +00001060 "Comparison between bytearray and string", 1))
Christian Heimes44720832008-05-26 13:01:01 +00001061 return NULL;
1062 }
1063
1064 Py_INCREF(Py_NotImplemented);
1065 return Py_NotImplemented;
1066 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001067#endif
Christian Heimes44720832008-05-26 13:01:01 +00001068
1069 self_size = _getbuffer(self, &self_bytes);
1070 if (self_size < 0) {
1071 PyErr_Clear();
1072 Py_INCREF(Py_NotImplemented);
1073 return Py_NotImplemented;
1074 }
1075
1076 other_size = _getbuffer(other, &other_bytes);
1077 if (other_size < 0) {
1078 PyErr_Clear();
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001079 PyBuffer_Release(&self_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001080 Py_INCREF(Py_NotImplemented);
1081 return Py_NotImplemented;
1082 }
1083
1084 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1085 /* Shortcut: if the lengths differ, the objects differ */
1086 cmp = (op == Py_NE);
1087 }
1088 else {
1089 minsize = self_size;
1090 if (other_size < minsize)
1091 minsize = other_size;
1092
1093 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1094 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1095
1096 if (cmp == 0) {
1097 if (self_size < other_size)
1098 cmp = -1;
1099 else if (self_size > other_size)
1100 cmp = 1;
1101 }
1102
1103 switch (op) {
1104 case Py_LT: cmp = cmp < 0; break;
1105 case Py_LE: cmp = cmp <= 0; break;
1106 case Py_EQ: cmp = cmp == 0; break;
1107 case Py_NE: cmp = cmp != 0; break;
1108 case Py_GT: cmp = cmp > 0; break;
1109 case Py_GE: cmp = cmp >= 0; break;
1110 }
1111 }
1112
1113 res = cmp ? Py_True : Py_False;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001114 PyBuffer_Release(&self_bytes);
1115 PyBuffer_Release(&other_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001116 Py_INCREF(res);
1117 return res;
1118}
1119
1120static void
Benjamin Petersond6720012009-04-18 15:31:34 +00001121bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00001122{
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001123 if (self->ob_exports > 0) {
1124 PyErr_SetString(PyExc_SystemError,
Georg Brandl517cfdc2009-04-05 13:16:35 +00001125 "deallocated bytearray object has exported buffers");
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001126 PyErr_Print();
1127 }
Christian Heimes44720832008-05-26 13:01:01 +00001128 if (self->ob_bytes != 0) {
1129 PyMem_Free(self->ob_bytes);
1130 }
1131 Py_TYPE(self)->tp_free((PyObject *)self);
1132}
1133
1134
1135/* -------------------------------------------------------------------- */
1136/* Methods */
1137
1138#define STRINGLIB_CHAR char
Christian Heimes44720832008-05-26 13:01:01 +00001139#define STRINGLIB_LEN PyByteArray_GET_SIZE
1140#define STRINGLIB_STR PyByteArray_AS_STRING
1141#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrou64672132010-01-13 07:55:48 +00001142#define STRINGLIB_ISSPACE Py_ISSPACE
1143#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes44720832008-05-26 13:01:01 +00001144#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1145#define STRINGLIB_MUTABLE 1
1146
1147#include "stringlib/fastsearch.h"
1148#include "stringlib/count.h"
1149#include "stringlib/find.h"
1150#include "stringlib/partition.h"
Antoine Pitrou64672132010-01-13 07:55:48 +00001151#include "stringlib/split.h"
Christian Heimes44720832008-05-26 13:01:01 +00001152#include "stringlib/ctype.h"
1153#include "stringlib/transmogrify.h"
1154
1155
1156/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1157were copied from the old char* style string object. */
1158
Antoine Pitrou64672132010-01-13 07:55:48 +00001159/* helper macro to fixup start/end slice values */
1160#define ADJUST_INDICES(start, end, len) \
1161 if (end > len) \
1162 end = len; \
1163 else if (end < 0) { \
1164 end += len; \
1165 if (end < 0) \
1166 end = 0; \
1167 } \
1168 if (start < 0) { \
1169 start += len; \
1170 if (start < 0) \
1171 start = 0; \
1172 }
Christian Heimes44720832008-05-26 13:01:01 +00001173
1174Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Petersond6720012009-04-18 15:31:34 +00001175bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes44720832008-05-26 13:01:01 +00001176{
1177 PyObject *subobj;
1178 Py_buffer subbuf;
1179 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1180 Py_ssize_t res;
1181
Jesus Cea44e81682011-04-20 16:39:15 +02001182 if (!stringlib_parse_args_finds("find/rfind/index/rindex",
1183 args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001184 return -2;
1185 if (_getbuffer(subobj, &subbuf) < 0)
1186 return -2;
1187 if (dir > 0)
1188 res = stringlib_find_slice(
1189 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1190 subbuf.buf, subbuf.len, start, end);
1191 else
1192 res = stringlib_rfind_slice(
1193 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1194 subbuf.buf, subbuf.len, start, end);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001195 PyBuffer_Release(&subbuf);
Christian Heimes44720832008-05-26 13:01:01 +00001196 return res;
1197}
1198
1199PyDoc_STRVAR(find__doc__,
1200"B.find(sub [,start [,end]]) -> int\n\
1201\n\
1202Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran5e3a19d2011-07-27 23:36:51 +08001203such that sub is contained within B[start,end]. Optional\n\
Christian Heimes44720832008-05-26 13:01:01 +00001204arguments start and end are interpreted as in slice notation.\n\
1205\n\
1206Return -1 on failure.");
1207
1208static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001209bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001210{
Benjamin Petersond6720012009-04-18 15:31:34 +00001211 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001212 if (result == -2)
1213 return NULL;
1214 return PyInt_FromSsize_t(result);
1215}
1216
1217PyDoc_STRVAR(count__doc__,
1218"B.count(sub [,start [,end]]) -> int\n\
1219\n\
1220Return the number of non-overlapping occurrences of subsection sub in\n\
1221bytes B[start:end]. Optional arguments start and end are interpreted\n\
1222as in slice notation.");
1223
1224static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001225bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001226{
1227 PyObject *sub_obj;
1228 const char *str = PyByteArray_AS_STRING(self);
1229 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1230 Py_buffer vsub;
1231 PyObject *count_obj;
1232
Jesus Cea44e81682011-04-20 16:39:15 +02001233 if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001234 return NULL;
1235
1236 if (_getbuffer(sub_obj, &vsub) < 0)
1237 return NULL;
1238
Antoine Pitrou64672132010-01-13 07:55:48 +00001239 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes44720832008-05-26 13:01:01 +00001240
1241 count_obj = PyInt_FromSsize_t(
Antoine Pitrou64672132010-01-13 07:55:48 +00001242 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes44720832008-05-26 13:01:01 +00001243 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001244 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00001245 return count_obj;
1246}
1247
1248
1249PyDoc_STRVAR(index__doc__,
1250"B.index(sub [,start [,end]]) -> int\n\
1251\n\
1252Like B.find() but raise ValueError when the subsection is not found.");
1253
1254static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001255bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001256{
Benjamin Petersond6720012009-04-18 15:31:34 +00001257 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001258 if (result == -2)
1259 return NULL;
1260 if (result == -1) {
1261 PyErr_SetString(PyExc_ValueError,
1262 "subsection not found");
1263 return NULL;
1264 }
1265 return PyInt_FromSsize_t(result);
1266}
1267
1268
1269PyDoc_STRVAR(rfind__doc__,
1270"B.rfind(sub [,start [,end]]) -> int\n\
1271\n\
1272Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran5e3a19d2011-07-27 23:36:51 +08001273such that sub is contained within B[start,end]. Optional\n\
Christian Heimes44720832008-05-26 13:01:01 +00001274arguments start and end are interpreted as in slice notation.\n\
1275\n\
1276Return -1 on failure.");
1277
1278static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001279bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001280{
Benjamin Petersond6720012009-04-18 15:31:34 +00001281 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001282 if (result == -2)
1283 return NULL;
1284 return PyInt_FromSsize_t(result);
1285}
1286
1287
1288PyDoc_STRVAR(rindex__doc__,
1289"B.rindex(sub [,start [,end]]) -> int\n\
1290\n\
1291Like B.rfind() but raise ValueError when the subsection is not found.");
1292
1293static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001294bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001295{
Benjamin Petersond6720012009-04-18 15:31:34 +00001296 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001297 if (result == -2)
1298 return NULL;
1299 if (result == -1) {
1300 PyErr_SetString(PyExc_ValueError,
1301 "subsection not found");
1302 return NULL;
1303 }
1304 return PyInt_FromSsize_t(result);
1305}
1306
1307
1308static int
Benjamin Petersond6720012009-04-18 15:31:34 +00001309bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00001310{
1311 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1312 if (ival == -1 && PyErr_Occurred()) {
1313 Py_buffer varg;
1314 int pos;
1315 PyErr_Clear();
1316 if (_getbuffer(arg, &varg) < 0)
1317 return -1;
1318 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1319 varg.buf, varg.len, 0);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001320 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00001321 return pos >= 0;
1322 }
1323 if (ival < 0 || ival >= 256) {
1324 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1325 return -1;
1326 }
1327
1328 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1329}
1330
1331
1332/* Matches the end (direction >= 0) or start (direction < 0) of self
1333 * against substr, using the start and end arguments. Returns
1334 * -1 on error, 0 if not found and 1 if found.
1335 */
1336Py_LOCAL(int)
Benjamin Petersond6720012009-04-18 15:31:34 +00001337_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes44720832008-05-26 13:01:01 +00001338 Py_ssize_t end, int direction)
1339{
1340 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1341 const char* str;
1342 Py_buffer vsubstr;
1343 int rv = 0;
1344
1345 str = PyByteArray_AS_STRING(self);
1346
1347 if (_getbuffer(substr, &vsubstr) < 0)
1348 return -1;
1349
Antoine Pitrou64672132010-01-13 07:55:48 +00001350 ADJUST_INDICES(start, end, len);
Christian Heimes44720832008-05-26 13:01:01 +00001351
1352 if (direction < 0) {
1353 /* startswith */
1354 if (start+vsubstr.len > len) {
1355 goto done;
1356 }
1357 } else {
1358 /* endswith */
1359 if (end-start < vsubstr.len || start > len) {
1360 goto done;
1361 }
1362
1363 if (end-vsubstr.len > start)
1364 start = end - vsubstr.len;
1365 }
1366 if (end-start >= vsubstr.len)
1367 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1368
1369done:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001370 PyBuffer_Release(&vsubstr);
Christian Heimes44720832008-05-26 13:01:01 +00001371 return rv;
1372}
1373
1374
1375PyDoc_STRVAR(startswith__doc__,
1376"B.startswith(prefix [,start [,end]]) -> bool\n\
1377\n\
1378Return True if B starts with the specified prefix, False otherwise.\n\
1379With optional start, test B beginning at that position.\n\
1380With optional end, stop comparing B at that position.\n\
1381prefix can also be a tuple of strings to try.");
1382
1383static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001384bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001385{
1386 Py_ssize_t start = 0;
1387 Py_ssize_t end = PY_SSIZE_T_MAX;
1388 PyObject *subobj;
1389 int result;
1390
Jesus Cea44e81682011-04-20 16:39:15 +02001391 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001392 return NULL;
1393 if (PyTuple_Check(subobj)) {
1394 Py_ssize_t i;
1395 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001396 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001397 PyTuple_GET_ITEM(subobj, i),
1398 start, end, -1);
1399 if (result == -1)
1400 return NULL;
1401 else if (result) {
1402 Py_RETURN_TRUE;
1403 }
1404 }
1405 Py_RETURN_FALSE;
1406 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001407 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001408 if (result == -1)
1409 return NULL;
1410 else
1411 return PyBool_FromLong(result);
1412}
1413
1414PyDoc_STRVAR(endswith__doc__,
1415"B.endswith(suffix [,start [,end]]) -> bool\n\
1416\n\
1417Return True if B ends with the specified suffix, False otherwise.\n\
1418With optional start, test B beginning at that position.\n\
1419With optional end, stop comparing B at that position.\n\
1420suffix can also be a tuple of strings to try.");
1421
1422static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001423bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001424{
1425 Py_ssize_t start = 0;
1426 Py_ssize_t end = PY_SSIZE_T_MAX;
1427 PyObject *subobj;
1428 int result;
1429
Jesus Cea44e81682011-04-20 16:39:15 +02001430 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001431 return NULL;
1432 if (PyTuple_Check(subobj)) {
1433 Py_ssize_t i;
1434 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001435 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001436 PyTuple_GET_ITEM(subobj, i),
1437 start, end, +1);
1438 if (result == -1)
1439 return NULL;
1440 else if (result) {
1441 Py_RETURN_TRUE;
1442 }
1443 }
1444 Py_RETURN_FALSE;
1445 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001446 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001447 if (result == -1)
1448 return NULL;
1449 else
1450 return PyBool_FromLong(result);
1451}
1452
1453
1454PyDoc_STRVAR(translate__doc__,
1455"B.translate(table[, deletechars]) -> bytearray\n\
1456\n\
1457Return a copy of B, where all characters occurring in the\n\
1458optional argument deletechars are removed, and the remaining\n\
1459characters have been mapped through the given translation\n\
1460table, which must be a bytes object of length 256.");
1461
1462static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001463bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001464{
1465 register char *input, *output;
1466 register const char *table;
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001467 register Py_ssize_t i, c;
Christian Heimes44720832008-05-26 13:01:01 +00001468 PyObject *input_obj = (PyObject*)self;
1469 const char *output_start;
1470 Py_ssize_t inlen;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001471 PyObject *result = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001472 int trans_table[256];
Georg Brandl6425a2f2008-12-28 11:54:53 +00001473 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001474 Py_buffer vtable, vdel;
1475
1476 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1477 &tableobj, &delobj))
1478 return NULL;
1479
Georg Brandl6425a2f2008-12-28 11:54:53 +00001480 if (tableobj == Py_None) {
1481 table = NULL;
1482 tableobj = NULL;
1483 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00001484 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001485 } else {
1486 if (vtable.len != 256) {
1487 PyErr_SetString(PyExc_ValueError,
1488 "translation table must be 256 characters long");
Georg Brandlec812ca2009-07-22 11:57:15 +00001489 PyBuffer_Release(&vtable);
1490 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001491 }
1492 table = (const char*)vtable.buf;
Christian Heimes44720832008-05-26 13:01:01 +00001493 }
1494
1495 if (delobj != NULL) {
1496 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandlec812ca2009-07-22 11:57:15 +00001497 if (tableobj != NULL)
1498 PyBuffer_Release(&vtable);
1499 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001500 }
1501 }
1502 else {
1503 vdel.buf = NULL;
1504 vdel.len = 0;
1505 }
1506
Christian Heimes44720832008-05-26 13:01:01 +00001507 inlen = PyByteArray_GET_SIZE(input_obj);
1508 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1509 if (result == NULL)
1510 goto done;
1511 output_start = output = PyByteArray_AsString(result);
1512 input = PyByteArray_AS_STRING(input_obj);
1513
Georg Brandl6425a2f2008-12-28 11:54:53 +00001514 if (vdel.len == 0 && table != NULL) {
Christian Heimes44720832008-05-26 13:01:01 +00001515 /* If no deletions are required, use faster code */
1516 for (i = inlen; --i >= 0; ) {
1517 c = Py_CHARMASK(*input++);
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001518 *output++ = table[c];
Christian Heimes44720832008-05-26 13:01:01 +00001519 }
Christian Heimes44720832008-05-26 13:01:01 +00001520 goto done;
1521 }
Georg Brandl6425a2f2008-12-28 11:54:53 +00001522
1523 if (table == NULL) {
1524 for (i = 0; i < 256; i++)
1525 trans_table[i] = Py_CHARMASK(i);
1526 } else {
1527 for (i = 0; i < 256; i++)
1528 trans_table[i] = Py_CHARMASK(table[i]);
1529 }
Christian Heimes44720832008-05-26 13:01:01 +00001530
1531 for (i = 0; i < vdel.len; i++)
1532 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1533
1534 for (i = inlen; --i >= 0; ) {
1535 c = Py_CHARMASK(*input++);
1536 if (trans_table[c] != -1)
1537 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1538 continue;
Christian Heimes44720832008-05-26 13:01:01 +00001539 }
1540 /* Fix the size of the resulting string */
1541 if (inlen > 0)
1542 PyByteArray_Resize(result, output - output_start);
1543
1544done:
Georg Brandl6425a2f2008-12-28 11:54:53 +00001545 if (tableobj != NULL)
1546 PyBuffer_Release(&vtable);
Christian Heimes44720832008-05-26 13:01:01 +00001547 if (delobj != NULL)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001548 PyBuffer_Release(&vdel);
Christian Heimes44720832008-05-26 13:01:01 +00001549 return result;
1550}
1551
1552
Christian Heimes44720832008-05-26 13:01:01 +00001553/* find and count characters and substrings */
1554
1555#define findchar(target, target_len, c) \
1556 ((char *)memchr((const void *)(target), c, target_len))
1557
Christian Heimes44720832008-05-26 13:01:01 +00001558
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001559/* Bytes ops must return a string, create a copy */
Christian Heimes44720832008-05-26 13:01:01 +00001560Py_LOCAL(PyByteArrayObject *)
1561return_self(PyByteArrayObject *self)
1562{
Christian Heimes44720832008-05-26 13:01:01 +00001563 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1564 PyByteArray_AS_STRING(self),
1565 PyByteArray_GET_SIZE(self));
1566}
1567
1568Py_LOCAL_INLINE(Py_ssize_t)
1569countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1570{
1571 Py_ssize_t count=0;
1572 const char *start=target;
1573 const char *end=target+target_len;
1574
1575 while ( (start=findchar(start, end-start, c)) != NULL ) {
1576 count++;
1577 if (count >= maxcount)
1578 break;
1579 start += 1;
1580 }
1581 return count;
1582}
1583
Christian Heimes44720832008-05-26 13:01:01 +00001584
1585/* Algorithms for different cases of string replacement */
1586
1587/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1588Py_LOCAL(PyByteArrayObject *)
1589replace_interleave(PyByteArrayObject *self,
1590 const char *to_s, Py_ssize_t to_len,
1591 Py_ssize_t maxcount)
1592{
1593 char *self_s, *result_s;
1594 Py_ssize_t self_len, result_len;
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001595 Py_ssize_t count, i;
Christian Heimes44720832008-05-26 13:01:01 +00001596 PyByteArrayObject *result;
1597
1598 self_len = PyByteArray_GET_SIZE(self);
1599
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001600 /* 1 at the end plus 1 after every character;
1601 count = min(maxcount, self_len + 1) */
1602 if (maxcount <= self_len) {
Christian Heimes44720832008-05-26 13:01:01 +00001603 count = maxcount;
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001604 }
1605 else {
1606 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1607 count = self_len + 1;
1608 }
Christian Heimes44720832008-05-26 13:01:01 +00001609
1610 /* Check for overflow */
1611 /* result_len = count * to_len + self_len; */
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001612 assert(count > 0);
1613 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes44720832008-05-26 13:01:01 +00001614 PyErr_SetString(PyExc_OverflowError,
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001615 "replace bytes is too long");
Christian Heimes44720832008-05-26 13:01:01 +00001616 return NULL;
1617 }
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001618 result_len = count * to_len + self_len;
Christian Heimes44720832008-05-26 13:01:01 +00001619 if (! (result = (PyByteArrayObject *)
1620 PyByteArray_FromStringAndSize(NULL, result_len)) )
1621 return NULL;
1622
1623 self_s = PyByteArray_AS_STRING(self);
1624 result_s = PyByteArray_AS_STRING(result);
1625
1626 /* TODO: special case single character, which doesn't need memcpy */
1627
1628 /* Lay the first one down (guaranteed this will occur) */
1629 Py_MEMCPY(result_s, to_s, to_len);
1630 result_s += to_len;
1631 count -= 1;
1632
1633 for (i=0; i<count; i++) {
1634 *result_s++ = *self_s++;
1635 Py_MEMCPY(result_s, to_s, to_len);
1636 result_s += to_len;
1637 }
1638
1639 /* Copy the rest of the original string */
1640 Py_MEMCPY(result_s, self_s, self_len-i);
1641
1642 return result;
1643}
1644
1645/* Special case for deleting a single character */
1646/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1647Py_LOCAL(PyByteArrayObject *)
1648replace_delete_single_character(PyByteArrayObject *self,
1649 char from_c, Py_ssize_t maxcount)
1650{
1651 char *self_s, *result_s;
1652 char *start, *next, *end;
1653 Py_ssize_t self_len, result_len;
1654 Py_ssize_t count;
1655 PyByteArrayObject *result;
1656
1657 self_len = PyByteArray_GET_SIZE(self);
1658 self_s = PyByteArray_AS_STRING(self);
1659
1660 count = countchar(self_s, self_len, from_c, maxcount);
1661 if (count == 0) {
1662 return return_self(self);
1663 }
1664
1665 result_len = self_len - count; /* from_len == 1 */
1666 assert(result_len>=0);
1667
1668 if ( (result = (PyByteArrayObject *)
1669 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1670 return NULL;
1671 result_s = PyByteArray_AS_STRING(result);
1672
1673 start = self_s;
1674 end = self_s + self_len;
1675 while (count-- > 0) {
1676 next = findchar(start, end-start, from_c);
1677 if (next == NULL)
1678 break;
1679 Py_MEMCPY(result_s, start, next-start);
1680 result_s += (next-start);
1681 start = next+1;
1682 }
1683 Py_MEMCPY(result_s, start, end-start);
1684
1685 return result;
1686}
1687
1688/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1689
1690Py_LOCAL(PyByteArrayObject *)
1691replace_delete_substring(PyByteArrayObject *self,
1692 const char *from_s, Py_ssize_t from_len,
1693 Py_ssize_t maxcount)
1694{
1695 char *self_s, *result_s;
1696 char *start, *next, *end;
1697 Py_ssize_t self_len, result_len;
1698 Py_ssize_t count, offset;
1699 PyByteArrayObject *result;
1700
1701 self_len = PyByteArray_GET_SIZE(self);
1702 self_s = PyByteArray_AS_STRING(self);
1703
Antoine Pitrou64672132010-01-13 07:55:48 +00001704 count = stringlib_count(self_s, self_len,
1705 from_s, from_len,
1706 maxcount);
Christian Heimes44720832008-05-26 13:01:01 +00001707
1708 if (count == 0) {
1709 /* no matches */
1710 return return_self(self);
1711 }
1712
1713 result_len = self_len - (count * from_len);
1714 assert (result_len>=0);
1715
1716 if ( (result = (PyByteArrayObject *)
1717 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1718 return NULL;
1719
1720 result_s = PyByteArray_AS_STRING(result);
1721
1722 start = self_s;
1723 end = self_s + self_len;
1724 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001725 offset = stringlib_find(start, end-start,
1726 from_s, from_len,
1727 0);
Christian Heimes44720832008-05-26 13:01:01 +00001728 if (offset == -1)
1729 break;
1730 next = start + offset;
1731
1732 Py_MEMCPY(result_s, start, next-start);
1733
1734 result_s += (next-start);
1735 start = next+from_len;
1736 }
1737 Py_MEMCPY(result_s, start, end-start);
1738 return result;
1739}
1740
1741/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1742Py_LOCAL(PyByteArrayObject *)
1743replace_single_character_in_place(PyByteArrayObject *self,
1744 char from_c, char to_c,
1745 Py_ssize_t maxcount)
1746{
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001747 char *self_s, *result_s, *start, *end, *next;
1748 Py_ssize_t self_len;
1749 PyByteArrayObject *result;
Christian Heimes44720832008-05-26 13:01:01 +00001750
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001751 /* The result string will be the same size */
1752 self_s = PyByteArray_AS_STRING(self);
1753 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes44720832008-05-26 13:01:01 +00001754
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001755 next = findchar(self_s, self_len, from_c);
Christian Heimes44720832008-05-26 13:01:01 +00001756
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001757 if (next == NULL) {
1758 /* No matches; return the original bytes */
1759 return return_self(self);
1760 }
Christian Heimes44720832008-05-26 13:01:01 +00001761
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001762 /* Need to make a new bytes */
1763 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1764 if (result == NULL)
1765 return NULL;
1766 result_s = PyByteArray_AS_STRING(result);
1767 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes44720832008-05-26 13:01:01 +00001768
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001769 /* change everything in-place, starting with this one */
1770 start = result_s + (next-self_s);
1771 *start = to_c;
1772 start++;
1773 end = result_s + self_len;
Christian Heimes44720832008-05-26 13:01:01 +00001774
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001775 while (--maxcount > 0) {
1776 next = findchar(start, end-start, from_c);
1777 if (next == NULL)
1778 break;
1779 *next = to_c;
1780 start = next+1;
1781 }
Christian Heimes44720832008-05-26 13:01:01 +00001782
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001783 return result;
Christian Heimes44720832008-05-26 13:01:01 +00001784}
1785
1786/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1787Py_LOCAL(PyByteArrayObject *)
1788replace_substring_in_place(PyByteArrayObject *self,
1789 const char *from_s, Py_ssize_t from_len,
1790 const char *to_s, Py_ssize_t to_len,
1791 Py_ssize_t maxcount)
1792{
1793 char *result_s, *start, *end;
1794 char *self_s;
1795 Py_ssize_t self_len, offset;
1796 PyByteArrayObject *result;
1797
1798 /* The result bytes will be the same size */
1799
1800 self_s = PyByteArray_AS_STRING(self);
1801 self_len = PyByteArray_GET_SIZE(self);
1802
Antoine Pitrou64672132010-01-13 07:55:48 +00001803 offset = stringlib_find(self_s, self_len,
1804 from_s, from_len,
1805 0);
Christian Heimes44720832008-05-26 13:01:01 +00001806 if (offset == -1) {
1807 /* No matches; return the original bytes */
1808 return return_self(self);
1809 }
1810
1811 /* Need to make a new bytes */
1812 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1813 if (result == NULL)
1814 return NULL;
1815 result_s = PyByteArray_AS_STRING(result);
1816 Py_MEMCPY(result_s, self_s, self_len);
1817
1818 /* change everything in-place, starting with this one */
1819 start = result_s + offset;
1820 Py_MEMCPY(start, to_s, from_len);
1821 start += from_len;
1822 end = result_s + self_len;
1823
1824 while ( --maxcount > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001825 offset = stringlib_find(start, end-start,
1826 from_s, from_len,
1827 0);
Christian Heimes44720832008-05-26 13:01:01 +00001828 if (offset==-1)
1829 break;
1830 Py_MEMCPY(start+offset, to_s, from_len);
1831 start += offset+from_len;
1832 }
1833
1834 return result;
1835}
1836
1837/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1838Py_LOCAL(PyByteArrayObject *)
1839replace_single_character(PyByteArrayObject *self,
1840 char from_c,
1841 const char *to_s, Py_ssize_t to_len,
1842 Py_ssize_t maxcount)
1843{
1844 char *self_s, *result_s;
1845 char *start, *next, *end;
1846 Py_ssize_t self_len, result_len;
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001847 Py_ssize_t count;
Christian Heimes44720832008-05-26 13:01:01 +00001848 PyByteArrayObject *result;
1849
1850 self_s = PyByteArray_AS_STRING(self);
1851 self_len = PyByteArray_GET_SIZE(self);
1852
1853 count = countchar(self_s, self_len, from_c, maxcount);
1854 if (count == 0) {
1855 /* no matches, return unchanged */
1856 return return_self(self);
1857 }
1858
1859 /* use the difference between current and new, hence the "-1" */
1860 /* result_len = self_len + count * (to_len-1) */
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001861 assert(count > 0);
1862 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes44720832008-05-26 13:01:01 +00001863 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1864 return NULL;
1865 }
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001866 result_len = self_len + count * (to_len - 1);
Christian Heimes44720832008-05-26 13:01:01 +00001867
1868 if ( (result = (PyByteArrayObject *)
1869 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1870 return NULL;
1871 result_s = PyByteArray_AS_STRING(result);
1872
1873 start = self_s;
1874 end = self_s + self_len;
1875 while (count-- > 0) {
1876 next = findchar(start, end-start, from_c);
1877 if (next == NULL)
1878 break;
1879
1880 if (next == start) {
1881 /* replace with the 'to' */
1882 Py_MEMCPY(result_s, to_s, to_len);
1883 result_s += to_len;
1884 start += 1;
1885 } else {
1886 /* copy the unchanged old then the 'to' */
1887 Py_MEMCPY(result_s, start, next-start);
1888 result_s += (next-start);
1889 Py_MEMCPY(result_s, to_s, to_len);
1890 result_s += to_len;
1891 start = next+1;
1892 }
1893 }
1894 /* Copy the remainder of the remaining bytes */
1895 Py_MEMCPY(result_s, start, end-start);
1896
1897 return result;
1898}
1899
1900/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1901Py_LOCAL(PyByteArrayObject *)
1902replace_substring(PyByteArrayObject *self,
1903 const char *from_s, Py_ssize_t from_len,
1904 const char *to_s, Py_ssize_t to_len,
1905 Py_ssize_t maxcount)
1906{
1907 char *self_s, *result_s;
1908 char *start, *next, *end;
1909 Py_ssize_t self_len, result_len;
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001910 Py_ssize_t count, offset;
Christian Heimes44720832008-05-26 13:01:01 +00001911 PyByteArrayObject *result;
1912
1913 self_s = PyByteArray_AS_STRING(self);
1914 self_len = PyByteArray_GET_SIZE(self);
1915
Antoine Pitrou64672132010-01-13 07:55:48 +00001916 count = stringlib_count(self_s, self_len,
1917 from_s, from_len,
1918 maxcount);
1919
Christian Heimes44720832008-05-26 13:01:01 +00001920 if (count == 0) {
1921 /* no matches, return unchanged */
1922 return return_self(self);
1923 }
1924
1925 /* Check for overflow */
1926 /* result_len = self_len + count * (to_len-from_len) */
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001927 assert(count > 0);
1928 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes44720832008-05-26 13:01:01 +00001929 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1930 return NULL;
1931 }
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001932 result_len = self_len + count * (to_len - from_len);
Christian Heimes44720832008-05-26 13:01:01 +00001933
1934 if ( (result = (PyByteArrayObject *)
1935 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1936 return NULL;
1937 result_s = PyByteArray_AS_STRING(result);
1938
1939 start = self_s;
1940 end = self_s + self_len;
1941 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001942 offset = stringlib_find(start, end-start,
1943 from_s, from_len,
1944 0);
Christian Heimes44720832008-05-26 13:01:01 +00001945 if (offset == -1)
1946 break;
1947 next = start+offset;
1948 if (next == start) {
1949 /* replace with the 'to' */
1950 Py_MEMCPY(result_s, to_s, to_len);
1951 result_s += to_len;
1952 start += from_len;
1953 } else {
1954 /* copy the unchanged old then the 'to' */
1955 Py_MEMCPY(result_s, start, next-start);
1956 result_s += (next-start);
1957 Py_MEMCPY(result_s, to_s, to_len);
1958 result_s += to_len;
1959 start = next+from_len;
1960 }
1961 }
1962 /* Copy the remainder of the remaining bytes */
1963 Py_MEMCPY(result_s, start, end-start);
1964
1965 return result;
1966}
1967
1968
1969Py_LOCAL(PyByteArrayObject *)
1970replace(PyByteArrayObject *self,
1971 const char *from_s, Py_ssize_t from_len,
1972 const char *to_s, Py_ssize_t to_len,
1973 Py_ssize_t maxcount)
1974{
1975 if (maxcount < 0) {
1976 maxcount = PY_SSIZE_T_MAX;
1977 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1978 /* nothing to do; return the original bytes */
1979 return return_self(self);
1980 }
1981
1982 if (maxcount == 0 ||
1983 (from_len == 0 && to_len == 0)) {
1984 /* nothing to do; return the original bytes */
1985 return return_self(self);
1986 }
1987
1988 /* Handle zero-length special cases */
1989
1990 if (from_len == 0) {
1991 /* insert the 'to' bytes everywhere. */
1992 /* >>> "Python".replace("", ".") */
1993 /* '.P.y.t.h.o.n.' */
1994 return replace_interleave(self, to_s, to_len, maxcount);
1995 }
1996
1997 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1998 /* point for an empty self bytes to generate a non-empty bytes */
1999 /* Special case so the remaining code always gets a non-empty bytes */
2000 if (PyByteArray_GET_SIZE(self) == 0) {
2001 return return_self(self);
2002 }
2003
2004 if (to_len == 0) {
Martin Panter440bbd02016-09-08 05:22:16 +00002005 /* delete all occurrences of 'from' bytes */
Christian Heimes44720832008-05-26 13:01:01 +00002006 if (from_len == 1) {
2007 return replace_delete_single_character(
2008 self, from_s[0], maxcount);
2009 } else {
2010 return replace_delete_substring(self, from_s, from_len, maxcount);
2011 }
2012 }
2013
2014 /* Handle special case where both bytes have the same length */
2015
2016 if (from_len == to_len) {
2017 if (from_len == 1) {
2018 return replace_single_character_in_place(
2019 self,
2020 from_s[0],
2021 to_s[0],
2022 maxcount);
2023 } else {
2024 return replace_substring_in_place(
2025 self, from_s, from_len, to_s, to_len, maxcount);
2026 }
2027 }
2028
2029 /* Otherwise use the more generic algorithms */
2030 if (from_len == 1) {
2031 return replace_single_character(self, from_s[0],
2032 to_s, to_len, maxcount);
2033 } else {
2034 /* len('from')>=2, len('to')>=1 */
2035 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2036 }
2037}
2038
2039
2040PyDoc_STRVAR(replace__doc__,
2041"B.replace(old, new[, count]) -> bytes\n\
2042\n\
2043Return a copy of B with all occurrences of subsection\n\
2044old replaced by new. If the optional argument count is\n\
2045given, only the first count occurrences are replaced.");
2046
2047static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002048bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002049{
2050 Py_ssize_t count = -1;
2051 PyObject *from, *to, *res;
2052 Py_buffer vfrom, vto;
2053
2054 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2055 return NULL;
2056
2057 if (_getbuffer(from, &vfrom) < 0)
2058 return NULL;
2059 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002060 PyBuffer_Release(&vfrom);
Christian Heimes44720832008-05-26 13:01:01 +00002061 return NULL;
2062 }
2063
2064 res = (PyObject *)replace((PyByteArrayObject *) self,
2065 vfrom.buf, vfrom.len,
2066 vto.buf, vto.len, count);
2067
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002068 PyBuffer_Release(&vfrom);
2069 PyBuffer_Release(&vto);
Christian Heimes44720832008-05-26 13:01:01 +00002070 return res;
2071}
2072
Christian Heimes44720832008-05-26 13:01:01 +00002073PyDoc_STRVAR(split__doc__,
2074"B.split([sep[, maxsplit]]) -> list of bytearray\n\
2075\n\
2076Return a list of the sections in B, using sep as the delimiter.\n\
2077If sep is not given, B is split on ASCII whitespace characters\n\
2078(space, tab, return, newline, formfeed, vertical tab).\n\
2079If maxsplit is given, at most maxsplit splits are done.");
2080
2081static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002082bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002083{
Antoine Pitrou64672132010-01-13 07:55:48 +00002084 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2085 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002086 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002087 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002088 Py_buffer vsub;
Christian Heimes44720832008-05-26 13:01:01 +00002089
2090 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2091 return NULL;
2092 if (maxsplit < 0)
2093 maxsplit = PY_SSIZE_T_MAX;
2094
2095 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002096 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002097
2098 if (_getbuffer(subobj, &vsub) < 0)
2099 return NULL;
2100 sub = vsub.buf;
2101 n = vsub.len;
2102
Antoine Pitrou64672132010-01-13 07:55:48 +00002103 list = stringlib_split(
2104 (PyObject*) self, s, len, sub, n, maxsplit
2105 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002106 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002107 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002108}
2109
2110PyDoc_STRVAR(partition__doc__,
2111"B.partition(sep) -> (head, sep, tail)\n\
2112\n\
2113Searches for the separator sep in B, and returns the part before it,\n\
2114the separator itself, and the part after it. If the separator is not\n\
2115found, returns B and two empty bytearray objects.");
2116
2117static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002118bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002119{
2120 PyObject *bytesep, *result;
2121
Serhiy Storchaka107f3cc2017-10-29 12:25:38 +02002122 bytesep = _PyByteArray_FromBufferObject(sep_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002123 if (! bytesep)
2124 return NULL;
2125
2126 result = stringlib_partition(
2127 (PyObject*) self,
2128 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2129 bytesep,
2130 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2131 );
2132
2133 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002134 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002135}
2136
2137PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti1fafaab2010-01-25 11:24:37 +00002138"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes44720832008-05-26 13:01:01 +00002139\n\
2140Searches for the separator sep in B, starting at the end of B,\n\
2141and returns the part before it, the separator itself, and the\n\
2142part after it. If the separator is not found, returns two empty\n\
2143bytearray objects and B.");
2144
2145static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002146bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002147{
2148 PyObject *bytesep, *result;
2149
Serhiy Storchaka107f3cc2017-10-29 12:25:38 +02002150 bytesep = _PyByteArray_FromBufferObject(sep_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002151 if (! bytesep)
2152 return NULL;
2153
2154 result = stringlib_rpartition(
2155 (PyObject*) self,
2156 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2157 bytesep,
2158 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2159 );
2160
2161 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002162 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002163}
2164
2165PyDoc_STRVAR(rsplit__doc__,
2166"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2167\n\
2168Return a list of the sections in B, using sep as the delimiter,\n\
2169starting at the end of B and working to the front.\n\
2170If sep is not given, B is split on ASCII whitespace characters\n\
2171(space, tab, return, newline, formfeed, vertical tab).\n\
2172If maxsplit is given, at most maxsplit splits are done.");
2173
2174static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002175bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002176{
Antoine Pitrou64672132010-01-13 07:55:48 +00002177 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2178 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002179 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002180 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002181 Py_buffer vsub;
2182
2183 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2184 return NULL;
2185 if (maxsplit < 0)
2186 maxsplit = PY_SSIZE_T_MAX;
2187
2188 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002189 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002190
2191 if (_getbuffer(subobj, &vsub) < 0)
2192 return NULL;
2193 sub = vsub.buf;
2194 n = vsub.len;
2195
Antoine Pitrou64672132010-01-13 07:55:48 +00002196 list = stringlib_rsplit(
2197 (PyObject*) self, s, len, sub, n, maxsplit
2198 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002199 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002200 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002201}
2202
2203PyDoc_STRVAR(reverse__doc__,
2204"B.reverse() -> None\n\
2205\n\
2206Reverse the order of the values in B in place.");
2207static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002208bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes44720832008-05-26 13:01:01 +00002209{
2210 char swap, *head, *tail;
2211 Py_ssize_t i, j, n = Py_SIZE(self);
2212
2213 j = n / 2;
2214 head = self->ob_bytes;
2215 tail = head + n - 1;
2216 for (i = 0; i < j; i++) {
2217 swap = *head;
2218 *head++ = *tail;
2219 *tail-- = swap;
2220 }
2221
2222 Py_RETURN_NONE;
2223}
2224
2225PyDoc_STRVAR(insert__doc__,
2226"B.insert(index, int) -> None\n\
2227\n\
2228Insert a single item into the bytearray before the given index.");
2229static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002230bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002231{
Georg Brandl3e483f62008-07-16 22:57:41 +00002232 PyObject *value;
2233 int ival;
Christian Heimes44720832008-05-26 13:01:01 +00002234 Py_ssize_t where, n = Py_SIZE(self);
2235
Georg Brandl3e483f62008-07-16 22:57:41 +00002236 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes44720832008-05-26 13:01:01 +00002237 return NULL;
2238
2239 if (n == PY_SSIZE_T_MAX) {
2240 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002241 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002242 return NULL;
2243 }
Georg Brandl3e483f62008-07-16 22:57:41 +00002244 if (!_getbytevalue(value, &ival))
Christian Heimes44720832008-05-26 13:01:01 +00002245 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002246 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2247 return NULL;
2248
2249 if (where < 0) {
2250 where += n;
2251 if (where < 0)
2252 where = 0;
2253 }
2254 if (where > n)
2255 where = n;
2256 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl3e483f62008-07-16 22:57:41 +00002257 self->ob_bytes[where] = ival;
Christian Heimes44720832008-05-26 13:01:01 +00002258
2259 Py_RETURN_NONE;
2260}
2261
2262PyDoc_STRVAR(append__doc__,
2263"B.append(int) -> None\n\
2264\n\
2265Append a single item to the end of B.");
2266static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002267bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002268{
2269 int value;
2270 Py_ssize_t n = Py_SIZE(self);
2271
2272 if (! _getbytevalue(arg, &value))
2273 return NULL;
2274 if (n == PY_SSIZE_T_MAX) {
2275 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002276 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002277 return NULL;
2278 }
2279 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2280 return NULL;
2281
2282 self->ob_bytes[n] = value;
2283
2284 Py_RETURN_NONE;
2285}
2286
2287PyDoc_STRVAR(extend__doc__,
2288"B.extend(iterable int) -> None\n\
2289\n\
2290Append all the elements from the iterator or sequence to the\n\
2291end of B.");
2292static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002293bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002294{
Benjamin Petersond6720012009-04-18 15:31:34 +00002295 PyObject *it, *item, *bytearray_obj;
Christian Heimes44720832008-05-26 13:01:01 +00002296 Py_ssize_t buf_size = 0, len = 0;
2297 int value;
2298 char *buf;
2299
Benjamin Petersond6720012009-04-18 15:31:34 +00002300 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes44720832008-05-26 13:01:01 +00002301 if (PyObject_CheckBuffer(arg)) {
Benjamin Petersond6720012009-04-18 15:31:34 +00002302 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002303 return NULL;
2304
2305 Py_RETURN_NONE;
2306 }
2307
2308 it = PyObject_GetIter(arg);
2309 if (it == NULL)
2310 return NULL;
2311
Ezio Melotti24b07bc2011-03-15 18:55:01 +02002312 /* Try to determine the length of the argument. 32 is arbitrary. */
Christian Heimes44720832008-05-26 13:01:01 +00002313 buf_size = _PyObject_LengthHint(arg, 32);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002314 if (buf_size == -1) {
2315 Py_DECREF(it);
2316 return NULL;
2317 }
Christian Heimes44720832008-05-26 13:01:01 +00002318
Benjamin Petersond6720012009-04-18 15:31:34 +00002319 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitroufe941772012-04-01 16:05:46 +02002320 if (bytearray_obj == NULL) {
2321 Py_DECREF(it);
Christian Heimes44720832008-05-26 13:01:01 +00002322 return NULL;
Antoine Pitroufe941772012-04-01 16:05:46 +02002323 }
Benjamin Petersond6720012009-04-18 15:31:34 +00002324 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002325
2326 while ((item = PyIter_Next(it)) != NULL) {
2327 if (! _getbytevalue(item, &value)) {
2328 Py_DECREF(item);
2329 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002330 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002331 return NULL;
2332 }
2333 buf[len++] = value;
2334 Py_DECREF(item);
2335
2336 if (len >= buf_size) {
Martin Panter0c08fe02016-07-18 07:53:13 +00002337 Py_ssize_t addition;
2338 if (len == PY_SSIZE_T_MAX) {
2339 Py_DECREF(it);
2340 Py_DECREF(bytearray_obj);
2341 return PyErr_NoMemory();
2342 }
2343 addition = len >> 1;
2344 if (addition > PY_SSIZE_T_MAX - len - 1)
2345 buf_size = PY_SSIZE_T_MAX;
2346 else
2347 buf_size = len + addition + 1;
Benjamin Petersond6720012009-04-18 15:31:34 +00002348 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00002349 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002350 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002351 return NULL;
2352 }
2353 /* Recompute the `buf' pointer, since the resizing operation may
2354 have invalidated it. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002355 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002356 }
2357 }
2358 Py_DECREF(it);
2359
2360 /* Resize down to exact size. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002361 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2362 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002363 return NULL;
2364 }
2365
Antoine Pitroufe941772012-04-01 16:05:46 +02002366 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2367 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002368 return NULL;
Antoine Pitroufe941772012-04-01 16:05:46 +02002369 }
Benjamin Petersond6720012009-04-18 15:31:34 +00002370 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002371
2372 Py_RETURN_NONE;
2373}
2374
2375PyDoc_STRVAR(pop__doc__,
2376"B.pop([index]) -> int\n\
2377\n\
2378Remove and return a single item from B. If no index\n\
Andrew M. Kuchlingd8972642008-06-21 13:29:12 +00002379argument is given, will pop the last value.");
Christian Heimes44720832008-05-26 13:01:01 +00002380static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002381bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002382{
2383 int value;
2384 Py_ssize_t where = -1, n = Py_SIZE(self);
2385
2386 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2387 return NULL;
2388
2389 if (n == 0) {
Eli Bendersky680e6eb2011-03-04 06:14:56 +00002390 PyErr_SetString(PyExc_IndexError,
2391 "pop from empty bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002392 return NULL;
2393 }
2394 if (where < 0)
2395 where += Py_SIZE(self);
2396 if (where < 0 || where >= Py_SIZE(self)) {
2397 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2398 return NULL;
2399 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002400 if (!_canresize(self))
2401 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002402
2403 value = self->ob_bytes[where];
2404 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2405 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2406 return NULL;
2407
Mark Dickinsonc8a7c7c2009-09-06 10:03:31 +00002408 return PyInt_FromLong((unsigned char)value);
Christian Heimes44720832008-05-26 13:01:01 +00002409}
2410
2411PyDoc_STRVAR(remove__doc__,
2412"B.remove(int) -> None\n\
2413\n\
Martin Panter440bbd02016-09-08 05:22:16 +00002414Remove the first occurrence of a value in B.");
Christian Heimes44720832008-05-26 13:01:01 +00002415static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002416bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002417{
2418 int value;
Serhiy Storchakac742dff2016-05-16 22:15:57 +03002419 Py_ssize_t n = Py_SIZE(self);
2420 char *where;
Christian Heimes44720832008-05-26 13:01:01 +00002421
2422 if (! _getbytevalue(arg, &value))
2423 return NULL;
2424
Serhiy Storchakac742dff2016-05-16 22:15:57 +03002425 where = memchr(self->ob_bytes, value, n);
2426 if (!where) {
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002427 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002428 return NULL;
2429 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002430 if (!_canresize(self))
2431 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002432
Serhiy Storchakac742dff2016-05-16 22:15:57 +03002433 memmove(where, where + 1, self->ob_bytes + n - where);
Christian Heimes44720832008-05-26 13:01:01 +00002434 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2435 return NULL;
2436
2437 Py_RETURN_NONE;
2438}
2439
2440/* XXX These two helpers could be optimized if argsize == 1 */
2441
2442static Py_ssize_t
2443lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2444 void *argptr, Py_ssize_t argsize)
2445{
2446 Py_ssize_t i = 0;
2447 while (i < mysize && memchr(argptr, myptr[i], argsize))
2448 i++;
2449 return i;
2450}
2451
2452static Py_ssize_t
2453rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2454 void *argptr, Py_ssize_t argsize)
2455{
2456 Py_ssize_t i = mysize - 1;
2457 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2458 i--;
2459 return i + 1;
2460}
2461
2462PyDoc_STRVAR(strip__doc__,
2463"B.strip([bytes]) -> bytearray\n\
2464\n\
2465Strip leading and trailing bytes contained in the argument.\n\
2466If the argument is omitted, strip ASCII whitespace.");
2467static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002468bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002469{
2470 Py_ssize_t left, right, mysize, argsize;
2471 void *myptr, *argptr;
2472 PyObject *arg = Py_None;
2473 Py_buffer varg;
2474 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2475 return NULL;
2476 if (arg == Py_None) {
2477 argptr = "\t\n\r\f\v ";
2478 argsize = 6;
2479 }
2480 else {
2481 if (_getbuffer(arg, &varg) < 0)
2482 return NULL;
2483 argptr = varg.buf;
2484 argsize = varg.len;
2485 }
2486 myptr = self->ob_bytes;
2487 mysize = Py_SIZE(self);
2488 left = lstrip_helper(myptr, mysize, argptr, argsize);
2489 if (left == mysize)
2490 right = left;
2491 else
2492 right = rstrip_helper(myptr, mysize, argptr, argsize);
2493 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002494 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002495 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2496}
2497
2498PyDoc_STRVAR(lstrip__doc__,
2499"B.lstrip([bytes]) -> bytearray\n\
2500\n\
2501Strip leading bytes contained in the argument.\n\
2502If the argument is omitted, strip leading ASCII whitespace.");
2503static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002504bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002505{
2506 Py_ssize_t left, right, mysize, argsize;
2507 void *myptr, *argptr;
2508 PyObject *arg = Py_None;
2509 Py_buffer varg;
2510 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2511 return NULL;
2512 if (arg == Py_None) {
2513 argptr = "\t\n\r\f\v ";
2514 argsize = 6;
2515 }
2516 else {
2517 if (_getbuffer(arg, &varg) < 0)
2518 return NULL;
2519 argptr = varg.buf;
2520 argsize = varg.len;
2521 }
2522 myptr = self->ob_bytes;
2523 mysize = Py_SIZE(self);
2524 left = lstrip_helper(myptr, mysize, argptr, argsize);
2525 right = mysize;
2526 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002527 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002528 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2529}
2530
2531PyDoc_STRVAR(rstrip__doc__,
2532"B.rstrip([bytes]) -> bytearray\n\
2533\n\
2534Strip trailing bytes contained in the argument.\n\
2535If the argument is omitted, strip trailing ASCII whitespace.");
2536static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002537bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002538{
2539 Py_ssize_t left, right, mysize, argsize;
2540 void *myptr, *argptr;
2541 PyObject *arg = Py_None;
2542 Py_buffer varg;
2543 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2544 return NULL;
2545 if (arg == Py_None) {
2546 argptr = "\t\n\r\f\v ";
2547 argsize = 6;
2548 }
2549 else {
2550 if (_getbuffer(arg, &varg) < 0)
2551 return NULL;
2552 argptr = varg.buf;
2553 argsize = varg.len;
2554 }
2555 myptr = self->ob_bytes;
2556 mysize = Py_SIZE(self);
2557 left = 0;
2558 right = rstrip_helper(myptr, mysize, argptr, argsize);
2559 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002560 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002561 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2562}
2563
2564PyDoc_STRVAR(decode_doc,
2565"B.decode([encoding[, errors]]) -> unicode object.\n\
2566\n\
2567Decodes B using the codec registered for encoding. encoding defaults\n\
2568to the default encoding. errors may be given to set a different error\n\
2569handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2570a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2571as well as any other name registered with codecs.register_error that is\n\
2572able to handle UnicodeDecodeErrors.");
2573
2574static PyObject *
Benjamin Petersondc782b52009-09-18 21:46:21 +00002575bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes44720832008-05-26 13:01:01 +00002576{
2577 const char *encoding = NULL;
2578 const char *errors = NULL;
Benjamin Petersondc782b52009-09-18 21:46:21 +00002579 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes44720832008-05-26 13:01:01 +00002580
Benjamin Petersondc782b52009-09-18 21:46:21 +00002581 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes44720832008-05-26 13:01:01 +00002582 return NULL;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002583 if (encoding == NULL) {
2584#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002585 encoding = PyUnicode_GetDefaultEncoding();
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002586#else
2587 PyErr_SetString(PyExc_ValueError, "no encoding specified");
2588 return NULL;
2589#endif
2590 }
Serhiy Storchakac7797dc2015-05-31 20:21:00 +03002591 return _PyCodec_DecodeText(self, encoding, errors);
Christian Heimes44720832008-05-26 13:01:01 +00002592}
2593
2594PyDoc_STRVAR(alloc_doc,
2595"B.__alloc__() -> int\n\
2596\n\
2597Returns the number of bytes actually allocated.");
2598
2599static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002600bytearray_alloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002601{
2602 return PyInt_FromSsize_t(self->ob_alloc);
2603}
2604
2605PyDoc_STRVAR(join_doc,
2606"B.join(iterable_of_bytes) -> bytes\n\
2607\n\
2608Concatenates any number of bytearray objects, with B in between each pair.");
2609
2610static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002611bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002612{
2613 PyObject *seq;
2614 Py_ssize_t mysize = Py_SIZE(self);
2615 Py_ssize_t i;
2616 Py_ssize_t n;
2617 PyObject **items;
2618 Py_ssize_t totalsize = 0;
2619 PyObject *result;
2620 char *dest;
2621
2622 seq = PySequence_Fast(it, "can only join an iterable");
2623 if (seq == NULL)
2624 return NULL;
2625 n = PySequence_Fast_GET_SIZE(seq);
2626 items = PySequence_Fast_ITEMS(seq);
2627
2628 /* Compute the total size, and check that they are all bytes */
2629 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2630 for (i = 0; i < n; i++) {
2631 PyObject *obj = items[i];
2632 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2633 PyErr_Format(PyExc_TypeError,
2634 "can only join an iterable of bytes "
2635 "(item %ld has type '%.100s')",
2636 /* XXX %ld isn't right on Win64 */
2637 (long)i, Py_TYPE(obj)->tp_name);
2638 goto error;
2639 }
2640 if (i > 0)
2641 totalsize += mysize;
2642 totalsize += Py_SIZE(obj);
2643 if (totalsize < 0) {
2644 PyErr_NoMemory();
2645 goto error;
2646 }
2647 }
2648
2649 /* Allocate the result, and copy the bytes */
2650 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2651 if (result == NULL)
2652 goto error;
2653 dest = PyByteArray_AS_STRING(result);
2654 for (i = 0; i < n; i++) {
2655 PyObject *obj = items[i];
2656 Py_ssize_t size = Py_SIZE(obj);
2657 char *buf;
2658 if (PyByteArray_Check(obj))
2659 buf = PyByteArray_AS_STRING(obj);
2660 else
2661 buf = PyBytes_AS_STRING(obj);
2662 if (i) {
2663 memcpy(dest, self->ob_bytes, mysize);
2664 dest += mysize;
2665 }
2666 memcpy(dest, buf, size);
2667 dest += size;
2668 }
2669
2670 /* Done */
2671 Py_DECREF(seq);
2672 return result;
2673
2674 /* Error handling */
2675 error:
2676 Py_DECREF(seq);
2677 return NULL;
2678}
2679
Antoine Pitrou64672132010-01-13 07:55:48 +00002680PyDoc_STRVAR(splitlines__doc__,
Raymond Hettingeraad5b022012-06-02 01:42:58 -04002681"B.splitlines(keepends=False) -> list of lines\n\
Antoine Pitrou64672132010-01-13 07:55:48 +00002682\n\
2683Return a list of the lines in B, breaking at line boundaries.\n\
2684Line breaks are not included in the resulting list unless keepends\n\
2685is given and true.");
2686
2687static PyObject*
2688bytearray_splitlines(PyObject *self, PyObject *args)
2689{
2690 int keepends = 0;
2691
2692 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2693 return NULL;
2694
2695 return stringlib_splitlines(
2696 (PyObject*) self, PyByteArray_AS_STRING(self),
2697 PyByteArray_GET_SIZE(self), keepends
2698 );
2699}
2700
Christian Heimes44720832008-05-26 13:01:01 +00002701PyDoc_STRVAR(fromhex_doc,
2702"bytearray.fromhex(string) -> bytearray\n\
2703\n\
2704Create a bytearray object from a string of hexadecimal numbers.\n\
2705Spaces between two numbers are accepted.\n\
2706Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2707
2708static int
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002709hex_digit_to_int(char c)
Christian Heimes44720832008-05-26 13:01:01 +00002710{
Eric Smithcac7af62009-04-27 19:04:37 +00002711 if (Py_ISDIGIT(c))
Christian Heimes44720832008-05-26 13:01:01 +00002712 return c - '0';
2713 else {
Eric Smithcac7af62009-04-27 19:04:37 +00002714 if (Py_ISUPPER(c))
2715 c = Py_TOLOWER(c);
Christian Heimes44720832008-05-26 13:01:01 +00002716 if (c >= 'a' && c <= 'f')
2717 return c - 'a' + 10;
2718 }
2719 return -1;
2720}
2721
2722static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002723bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002724{
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002725 PyObject *newbytes;
Christian Heimes44720832008-05-26 13:01:01 +00002726 char *buf;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002727 char *hex;
Christian Heimes44720832008-05-26 13:01:01 +00002728 Py_ssize_t hexlen, byteslen, i, j;
2729 int top, bot;
2730
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002731 if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
Christian Heimes44720832008-05-26 13:01:01 +00002732 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002733 byteslen = hexlen/2; /* This overestimates if there are spaces */
2734 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2735 if (!newbytes)
2736 return NULL;
2737 buf = PyByteArray_AS_STRING(newbytes);
2738 for (i = j = 0; i < hexlen; i += 2) {
2739 /* skip over spaces in the input */
2740 while (hex[i] == ' ')
2741 i++;
2742 if (i >= hexlen)
2743 break;
2744 top = hex_digit_to_int(hex[i]);
2745 bot = hex_digit_to_int(hex[i+1]);
2746 if (top == -1 || bot == -1) {
2747 PyErr_Format(PyExc_ValueError,
2748 "non-hexadecimal number found in "
2749 "fromhex() arg at position %zd", i);
2750 goto error;
2751 }
2752 buf[j++] = (top << 4) + bot;
2753 }
2754 if (PyByteArray_Resize(newbytes, j) < 0)
2755 goto error;
2756 return newbytes;
2757
2758 error:
2759 Py_DECREF(newbytes);
2760 return NULL;
2761}
2762
2763PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2764
2765static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002766bytearray_reduce(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002767{
2768 PyObject *latin1, *dict;
2769 if (self->ob_bytes)
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002770#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002771 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2772 Py_SIZE(self), NULL);
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002773#else
Mark Dickinson9d109742009-10-15 15:18:55 +00002774 latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002775#endif
Christian Heimes44720832008-05-26 13:01:01 +00002776 else
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002777#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002778 latin1 = PyUnicode_FromString("");
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002779#else
2780 latin1 = PyString_FromString("");
2781#endif
Christian Heimes44720832008-05-26 13:01:01 +00002782
2783 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2784 if (dict == NULL) {
2785 PyErr_Clear();
2786 dict = Py_None;
2787 Py_INCREF(dict);
2788 }
2789
2790 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2791}
2792
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002793PyDoc_STRVAR(sizeof_doc,
2794"B.__sizeof__() -> int\n\
2795 \n\
2796Returns the size of B in memory, in bytes");
2797static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002798bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002799{
Georg Brandl517cfdc2009-04-05 13:16:35 +00002800 Py_ssize_t res;
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002801
Serhiy Storchakac06a6d02015-12-19 20:07:48 +02002802 res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002803 return PyInt_FromSsize_t(res);
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002804}
2805
Benjamin Petersond6720012009-04-18 15:31:34 +00002806static PySequenceMethods bytearray_as_sequence = {
2807 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes44720832008-05-26 13:01:01 +00002808 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Petersond6720012009-04-18 15:31:34 +00002809 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2810 (ssizeargfunc)bytearray_getitem, /* sq_item */
2811 0, /* sq_slice */
2812 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2813 0, /* sq_ass_slice */
2814 (objobjproc)bytearray_contains, /* sq_contains */
2815 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2816 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes44720832008-05-26 13:01:01 +00002817};
2818
Benjamin Petersond6720012009-04-18 15:31:34 +00002819static PyMappingMethods bytearray_as_mapping = {
2820 (lenfunc)bytearray_length,
2821 (binaryfunc)bytearray_subscript,
2822 (objobjargproc)bytearray_ass_subscript,
Christian Heimes44720832008-05-26 13:01:01 +00002823};
2824
Benjamin Petersond6720012009-04-18 15:31:34 +00002825static PyBufferProcs bytearray_as_buffer = {
2826 (readbufferproc)bytearray_buffer_getreadbuf,
2827 (writebufferproc)bytearray_buffer_getwritebuf,
2828 (segcountproc)bytearray_buffer_getsegcount,
2829 (charbufferproc)bytearray_buffer_getcharbuf,
2830 (getbufferproc)bytearray_getbuffer,
2831 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes44720832008-05-26 13:01:01 +00002832};
2833
2834static PyMethodDef
Benjamin Petersond6720012009-04-18 15:31:34 +00002835bytearray_methods[] = {
2836 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2837 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2838 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2839 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002840 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2841 _Py_capitalize__doc__},
2842 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002843 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Petersondc782b52009-09-18 21:46:21 +00002844 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002845 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002846 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2847 expandtabs__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002848 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2849 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2850 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes44720832008-05-26 13:01:01 +00002851 fromhex_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002852 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2853 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002854 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2855 _Py_isalnum__doc__},
2856 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2857 _Py_isalpha__doc__},
2858 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2859 _Py_isdigit__doc__},
2860 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2861 _Py_islower__doc__},
2862 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2863 _Py_isspace__doc__},
2864 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2865 _Py_istitle__doc__},
2866 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2867 _Py_isupper__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002868 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes44720832008-05-26 13:01:01 +00002869 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2870 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002871 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2872 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2873 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2874 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2875 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2876 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2877 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2878 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002879 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002880 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2881 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2882 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2883 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrou64672132010-01-13 07:55:48 +00002884 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002885 splitlines__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002886 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes44720832008-05-26 13:01:01 +00002887 startswith__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002888 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002889 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2890 _Py_swapcase__doc__},
2891 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002892 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002893 translate__doc__},
2894 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2895 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2896 {NULL}
2897};
2898
Benjamin Petersond6720012009-04-18 15:31:34 +00002899PyDoc_STRVAR(bytearray_doc,
Christian Heimes44720832008-05-26 13:01:01 +00002900"bytearray(iterable_of_ints) -> bytearray.\n\
2901bytearray(string, encoding[, errors]) -> bytearray.\n\
2902bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
2903bytearray(memory_view) -> bytearray.\n\
2904\n\
Serhiy Storchaka9a118f12016-04-17 09:37:36 +03002905Construct a mutable bytearray object from:\n\
Christian Heimes44720832008-05-26 13:01:01 +00002906 - an iterable yielding integers in range(256)\n\
2907 - a text string encoded using the specified encoding\n\
2908 - a bytes or a bytearray object\n\
2909 - any object implementing the buffer API.\n\
2910\n\
2911bytearray(int) -> bytearray.\n\
2912\n\
2913Construct a zero-initialized bytearray of the given length.");
2914
2915
Benjamin Petersond6720012009-04-18 15:31:34 +00002916static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes44720832008-05-26 13:01:01 +00002917
2918PyTypeObject PyByteArray_Type = {
2919 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2920 "bytearray",
2921 sizeof(PyByteArrayObject),
2922 0,
Benjamin Petersond6720012009-04-18 15:31:34 +00002923 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00002924 0, /* tp_print */
2925 0, /* tp_getattr */
2926 0, /* tp_setattr */
2927 0, /* tp_compare */
Benjamin Petersond6720012009-04-18 15:31:34 +00002928 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes44720832008-05-26 13:01:01 +00002929 0, /* tp_as_number */
Benjamin Petersond6720012009-04-18 15:31:34 +00002930 &bytearray_as_sequence, /* tp_as_sequence */
2931 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes44720832008-05-26 13:01:01 +00002932 0, /* tp_hash */
2933 0, /* tp_call */
Benjamin Petersond6720012009-04-18 15:31:34 +00002934 bytearray_str, /* tp_str */
Christian Heimes44720832008-05-26 13:01:01 +00002935 PyObject_GenericGetAttr, /* tp_getattro */
2936 0, /* tp_setattro */
Benjamin Petersond6720012009-04-18 15:31:34 +00002937 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes44720832008-05-26 13:01:01 +00002938 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2939 Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
Benjamin Petersond6720012009-04-18 15:31:34 +00002940 bytearray_doc, /* tp_doc */
Christian Heimes44720832008-05-26 13:01:01 +00002941 0, /* tp_traverse */
2942 0, /* tp_clear */
Benjamin Petersond6720012009-04-18 15:31:34 +00002943 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes44720832008-05-26 13:01:01 +00002944 0, /* tp_weaklistoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002945 bytearray_iter, /* tp_iter */
Christian Heimes44720832008-05-26 13:01:01 +00002946 0, /* tp_iternext */
Benjamin Petersond6720012009-04-18 15:31:34 +00002947 bytearray_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00002948 0, /* tp_members */
2949 0, /* tp_getset */
2950 0, /* tp_base */
2951 0, /* tp_dict */
2952 0, /* tp_descr_get */
2953 0, /* tp_descr_set */
2954 0, /* tp_dictoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002955 (initproc)bytearray_init, /* tp_init */
Christian Heimes44720832008-05-26 13:01:01 +00002956 PyType_GenericAlloc, /* tp_alloc */
2957 PyType_GenericNew, /* tp_new */
2958 PyObject_Del, /* tp_free */
2959};
2960
2961/*********************** Bytes Iterator ****************************/
2962
2963typedef struct {
2964 PyObject_HEAD
2965 Py_ssize_t it_index;
2966 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2967} bytesiterobject;
2968
2969static void
Benjamin Petersond6720012009-04-18 15:31:34 +00002970bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002971{
2972 _PyObject_GC_UNTRACK(it);
2973 Py_XDECREF(it->it_seq);
2974 PyObject_GC_Del(it);
2975}
2976
2977static int
Benjamin Petersond6720012009-04-18 15:31:34 +00002978bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002979{
2980 Py_VISIT(it->it_seq);
2981 return 0;
2982}
2983
2984static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002985bytearrayiter_next(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002986{
2987 PyByteArrayObject *seq;
2988 PyObject *item;
2989
2990 assert(it != NULL);
2991 seq = it->it_seq;
2992 if (seq == NULL)
2993 return NULL;
2994 assert(PyByteArray_Check(seq));
2995
2996 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2997 item = PyInt_FromLong(
2998 (unsigned char)seq->ob_bytes[it->it_index]);
2999 if (item != NULL)
3000 ++it->it_index;
3001 return item;
3002 }
3003
Christian Heimes44720832008-05-26 13:01:01 +00003004 it->it_seq = NULL;
Serhiy Storchaka14a7d632016-03-30 20:43:06 +03003005 Py_DECREF(seq);
Christian Heimes44720832008-05-26 13:01:01 +00003006 return NULL;
3007}
3008
3009static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003010bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00003011{
3012 Py_ssize_t len = 0;
3013 if (it->it_seq)
3014 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3015 return PyInt_FromSsize_t(len);
3016}
3017
3018PyDoc_STRVAR(length_hint_doc,
3019 "Private method returning an estimate of len(list(it)).");
3020
Benjamin Petersond6720012009-04-18 15:31:34 +00003021static PyMethodDef bytearrayiter_methods[] = {
3022 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes44720832008-05-26 13:01:01 +00003023 length_hint_doc},
3024 {NULL, NULL} /* sentinel */
3025};
3026
3027PyTypeObject PyByteArrayIter_Type = {
3028 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3029 "bytearray_iterator", /* tp_name */
3030 sizeof(bytesiterobject), /* tp_basicsize */
3031 0, /* tp_itemsize */
3032 /* methods */
Benjamin Petersond6720012009-04-18 15:31:34 +00003033 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00003034 0, /* tp_print */
3035 0, /* tp_getattr */
3036 0, /* tp_setattr */
3037 0, /* tp_compare */
3038 0, /* tp_repr */
3039 0, /* tp_as_number */
3040 0, /* tp_as_sequence */
3041 0, /* tp_as_mapping */
3042 0, /* tp_hash */
3043 0, /* tp_call */
3044 0, /* tp_str */
3045 PyObject_GenericGetAttr, /* tp_getattro */
3046 0, /* tp_setattro */
3047 0, /* tp_as_buffer */
3048 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3049 0, /* tp_doc */
Benjamin Petersond6720012009-04-18 15:31:34 +00003050 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes44720832008-05-26 13:01:01 +00003051 0, /* tp_clear */
3052 0, /* tp_richcompare */
3053 0, /* tp_weaklistoffset */
3054 PyObject_SelfIter, /* tp_iter */
Benjamin Petersond6720012009-04-18 15:31:34 +00003055 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3056 bytearrayiter_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00003057 0,
3058};
3059
3060static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003061bytearray_iter(PyObject *seq)
Christian Heimes44720832008-05-26 13:01:01 +00003062{
3063 bytesiterobject *it;
3064
3065 if (!PyByteArray_Check(seq)) {
3066 PyErr_BadInternalCall();
3067 return NULL;
3068 }
3069 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3070 if (it == NULL)
3071 return NULL;
3072 it->it_index = 0;
3073 Py_INCREF(seq);
3074 it->it_seq = (PyByteArrayObject *)seq;
3075 _PyObject_GC_TRACK(it);
3076 return (PyObject *)it;
3077}