blob: 8c17245266111806b32deb445ca7e2d519259970 [file] [log] [blame]
Christian Heimes44720832008-05-26 13:01:01 +00001/* PyBytes (bytearray) implementation */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
5#include "structmember.h"
6#include "bytes_methods.h"
7
Antoine Pitroue80a6a42010-01-17 12:26:20 +00008char _PyByteArray_empty_string[] = "";
Christian Heimes44720832008-05-26 13:01:01 +00009
10void
11PyByteArray_Fini(void)
12{
Christian Heimes44720832008-05-26 13:01:01 +000013}
14
15int
16PyByteArray_Init(void)
17{
Christian Heimes44720832008-05-26 13:01:01 +000018 return 1;
19}
20
21/* end nullbytes support */
22
23/* Helpers */
24
25static int
26_getbytevalue(PyObject* arg, int *value)
27{
28 long face_value;
29
Georg Brandl3e483f62008-07-16 22:57:41 +000030 if (PyBytes_CheckExact(arg)) {
Christian Heimes44720832008-05-26 13:01:01 +000031 if (Py_SIZE(arg) != 1) {
32 PyErr_SetString(PyExc_ValueError, "string must be of size 1");
33 return 0;
34 }
Georg Brandl3e483f62008-07-16 22:57:41 +000035 *value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
36 return 1;
37 }
38 else if (PyInt_Check(arg) || PyLong_Check(arg)) {
39 face_value = PyLong_AsLong(arg);
Christian Heimes44720832008-05-26 13:01:01 +000040 }
41 else {
Georg Brandl3e483f62008-07-16 22:57:41 +000042 PyObject *index = PyNumber_Index(arg);
43 if (index == NULL) {
44 PyErr_Format(PyExc_TypeError,
45 "an integer or string of size 1 is required");
46 return 0;
47 }
48 face_value = PyLong_AsLong(index);
49 Py_DECREF(index);
50 }
Georg Brandl3e483f62008-07-16 22:57:41 +000051
52 if (face_value < 0 || face_value >= 256) {
Georg Brandl3238a3e2008-07-16 23:17:46 +000053 /* this includes the OverflowError in case the long is too large */
Georg Brandl3e483f62008-07-16 22:57:41 +000054 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Christian Heimes44720832008-05-26 13:01:01 +000055 return 0;
56 }
57
58 *value = face_value;
59 return 1;
60}
61
62static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000063bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000064{
65 if ( index != 0 ) {
66 PyErr_SetString(PyExc_SystemError,
67 "accessing non-existent bytes segment");
68 return -1;
69 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +000070 *ptr = (void *)PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +000071 return Py_SIZE(self);
72}
73
74static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000075bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000076{
77 if ( index != 0 ) {
78 PyErr_SetString(PyExc_SystemError,
79 "accessing non-existent bytes segment");
80 return -1;
81 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +000082 *ptr = (void *)PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +000083 return Py_SIZE(self);
84}
85
86static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000087bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
Christian Heimes44720832008-05-26 13:01:01 +000088{
89 if ( lenp )
90 *lenp = Py_SIZE(self);
91 return 1;
92}
93
94static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000095bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000096{
97 if ( index != 0 ) {
98 PyErr_SetString(PyExc_SystemError,
99 "accessing non-existent bytes segment");
100 return -1;
101 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000102 *ptr = PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +0000103 return Py_SIZE(self);
104}
105
106static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000107bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes44720832008-05-26 13:01:01 +0000108{
Antoine Pitrou619f16e2010-06-09 16:24:00 +0000109 int ret;
110 void *ptr;
111 if (view == NULL) {
112 obj->ob_exports++;
113 return 0;
114 }
115 ptr = (void *) PyByteArray_AS_STRING(obj);
116 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
117 if (ret >= 0) {
118 obj->ob_exports++;
119 }
120 return ret;
Christian Heimes44720832008-05-26 13:01:01 +0000121}
122
123static void
Benjamin Petersond6720012009-04-18 15:31:34 +0000124bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes44720832008-05-26 13:01:01 +0000125{
Antoine Pitrou619f16e2010-06-09 16:24:00 +0000126 obj->ob_exports--;
Christian Heimes44720832008-05-26 13:01:01 +0000127}
128
129static Py_ssize_t
130_getbuffer(PyObject *obj, Py_buffer *view)
131{
132 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
133
134 if (buffer == NULL || buffer->bf_getbuffer == NULL)
135 {
136 PyErr_Format(PyExc_TypeError,
137 "Type %.100s doesn't support the buffer API",
138 Py_TYPE(obj)->tp_name);
139 return -1;
140 }
141
142 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
143 return -1;
144 return view->len;
145}
146
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000147static int
148_canresize(PyByteArrayObject *self)
149{
150 if (self->ob_exports > 0) {
151 PyErr_SetString(PyExc_BufferError,
152 "Existing exports of data: object cannot be re-sized");
153 return 0;
154 }
155 return 1;
156}
157
Christian Heimes44720832008-05-26 13:01:01 +0000158/* Direct API functions */
159
160PyObject *
161PyByteArray_FromObject(PyObject *input)
162{
163 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
164 input, NULL);
165}
166
167PyObject *
168PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
169{
170 PyByteArrayObject *new;
171 Py_ssize_t alloc;
172
173 if (size < 0) {
174 PyErr_SetString(PyExc_SystemError,
175 "Negative size passed to PyByteArray_FromStringAndSize");
176 return NULL;
177 }
178
179 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
180 if (new == NULL)
181 return NULL;
182
183 if (size == 0) {
184 new->ob_bytes = NULL;
185 alloc = 0;
186 }
187 else {
188 alloc = size + 1;
189 new->ob_bytes = PyMem_Malloc(alloc);
190 if (new->ob_bytes == NULL) {
191 Py_DECREF(new);
192 return PyErr_NoMemory();
193 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000194 if (bytes != NULL && size > 0)
Christian Heimes44720832008-05-26 13:01:01 +0000195 memcpy(new->ob_bytes, bytes, size);
196 new->ob_bytes[size] = '\0'; /* Trailing null byte */
197 }
198 Py_SIZE(new) = size;
199 new->ob_alloc = alloc;
200 new->ob_exports = 0;
201
202 return (PyObject *)new;
203}
204
205Py_ssize_t
206PyByteArray_Size(PyObject *self)
207{
208 assert(self != NULL);
209 assert(PyByteArray_Check(self));
210
211 return PyByteArray_GET_SIZE(self);
212}
213
214char *
215PyByteArray_AsString(PyObject *self)
216{
217 assert(self != NULL);
218 assert(PyByteArray_Check(self));
219
220 return PyByteArray_AS_STRING(self);
221}
222
223int
224PyByteArray_Resize(PyObject *self, Py_ssize_t size)
225{
226 void *sval;
227 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
228
229 assert(self != NULL);
230 assert(PyByteArray_Check(self));
231 assert(size >= 0);
232
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000233 if (size == Py_SIZE(self)) {
234 return 0;
235 }
236 if (!_canresize((PyByteArrayObject *)self)) {
237 return -1;
238 }
239
Christian Heimes44720832008-05-26 13:01:01 +0000240 if (size < alloc / 2) {
241 /* Major downsize; resize down to exact size */
242 alloc = size + 1;
243 }
244 else if (size < alloc) {
245 /* Within allocated size; quick exit */
246 Py_SIZE(self) = size;
247 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
248 return 0;
249 }
250 else if (size <= alloc * 1.125) {
251 /* Moderate upsize; overallocate similar to list_resize() */
252 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
253 }
254 else {
255 /* Major upsize; resize up to exact size */
256 alloc = size + 1;
257 }
258
Christian Heimes44720832008-05-26 13:01:01 +0000259 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
260 if (sval == NULL) {
261 PyErr_NoMemory();
262 return -1;
263 }
264
265 ((PyByteArrayObject *)self)->ob_bytes = sval;
266 Py_SIZE(self) = size;
267 ((PyByteArrayObject *)self)->ob_alloc = alloc;
268 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
269
270 return 0;
271}
272
273PyObject *
274PyByteArray_Concat(PyObject *a, PyObject *b)
275{
Christian Heimes44720832008-05-26 13:01:01 +0000276 Py_buffer va, vb;
277 PyByteArrayObject *result = NULL;
278
279 va.len = -1;
280 vb.len = -1;
281 if (_getbuffer(a, &va) < 0 ||
282 _getbuffer(b, &vb) < 0) {
283 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
284 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
285 goto done;
286 }
287
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300288 if (va.len > PY_SSIZE_T_MAX - vb.len) {
289 PyErr_NoMemory();
290 goto done;
Christian Heimes44720832008-05-26 13:01:01 +0000291 }
292
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300293 result = (PyByteArrayObject *) \
294 PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
Christian Heimes44720832008-05-26 13:01:01 +0000295 if (result != NULL) {
296 memcpy(result->ob_bytes, va.buf, va.len);
297 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
298 }
299
300 done:
301 if (va.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000302 PyBuffer_Release(&va);
Christian Heimes44720832008-05-26 13:01:01 +0000303 if (vb.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000304 PyBuffer_Release(&vb);
Christian Heimes44720832008-05-26 13:01:01 +0000305 return (PyObject *)result;
306}
307
308/* Functions stuffed into the type object */
309
310static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +0000311bytearray_length(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000312{
313 return Py_SIZE(self);
314}
315
316static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000317bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes44720832008-05-26 13:01:01 +0000318{
319 Py_ssize_t mysize;
320 Py_ssize_t size;
321 Py_buffer vo;
322
323 if (_getbuffer(other, &vo) < 0) {
324 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
325 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
326 return NULL;
327 }
328
329 mysize = Py_SIZE(self);
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300330 if (mysize > PY_SSIZE_T_MAX - vo.len) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000331 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000332 return PyErr_NoMemory();
333 }
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300334 size = mysize + vo.len;
Christian Heimes44720832008-05-26 13:01:01 +0000335 if (size < self->ob_alloc) {
336 Py_SIZE(self) = size;
337 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
338 }
339 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000340 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000341 return NULL;
342 }
343 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000344 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000345 Py_INCREF(self);
346 return (PyObject *)self;
347}
348
349static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000350bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000351{
352 PyByteArrayObject *result;
353 Py_ssize_t mysize;
354 Py_ssize_t size;
355
356 if (count < 0)
357 count = 0;
358 mysize = Py_SIZE(self);
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300359 if (count != 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes44720832008-05-26 13:01:01 +0000360 return PyErr_NoMemory();
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300361 size = mysize * count;
Christian Heimes44720832008-05-26 13:01:01 +0000362 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
363 if (result != NULL && size != 0) {
364 if (mysize == 1)
365 memset(result->ob_bytes, self->ob_bytes[0], size);
366 else {
367 Py_ssize_t i;
368 for (i = 0; i < count; i++)
369 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
370 }
371 }
372 return (PyObject *)result;
373}
374
375static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000376bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000377{
378 Py_ssize_t mysize;
379 Py_ssize_t size;
380
381 if (count < 0)
382 count = 0;
383 mysize = Py_SIZE(self);
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300384 if (count != 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes44720832008-05-26 13:01:01 +0000385 return PyErr_NoMemory();
Serhiy Storchaka373773d2016-07-12 15:46:57 +0300386 size = mysize * count;
Christian Heimes44720832008-05-26 13:01:01 +0000387 if (size < self->ob_alloc) {
388 Py_SIZE(self) = size;
389 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
390 }
391 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
392 return NULL;
393
394 if (mysize == 1)
395 memset(self->ob_bytes, self->ob_bytes[0], size);
396 else {
397 Py_ssize_t i;
398 for (i = 1; i < count; i++)
399 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
400 }
401
402 Py_INCREF(self);
403 return (PyObject *)self;
404}
405
406static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000407bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes44720832008-05-26 13:01:01 +0000408{
409 if (i < 0)
410 i += Py_SIZE(self);
411 if (i < 0 || i >= Py_SIZE(self)) {
412 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
413 return NULL;
414 }
415 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
416}
417
418static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000419bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes44720832008-05-26 13:01:01 +0000420{
Georg Brandl3e483f62008-07-16 22:57:41 +0000421 if (PyIndex_Check(index)) {
422 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000423
424 if (i == -1 && PyErr_Occurred())
425 return NULL;
426
427 if (i < 0)
428 i += PyByteArray_GET_SIZE(self);
429
430 if (i < 0 || i >= Py_SIZE(self)) {
431 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
432 return NULL;
433 }
434 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
435 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000436 else if (PySlice_Check(index)) {
Christian Heimes44720832008-05-26 13:01:01 +0000437 Py_ssize_t start, stop, step, slicelength, cur, i;
Serhiy Storchakae41390a2017-04-08 11:48:57 +0300438 if (_PySlice_Unpack((PySliceObject *)index, &start, &stop, &step) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +0000439 return NULL;
440 }
Serhiy Storchakae41390a2017-04-08 11:48:57 +0300441 slicelength = _PySlice_AdjustIndices(PyByteArray_GET_SIZE(self),
442 &start, &stop, step);
Christian Heimes44720832008-05-26 13:01:01 +0000443
444 if (slicelength <= 0)
445 return PyByteArray_FromStringAndSize("", 0);
446 else if (step == 1) {
447 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
448 slicelength);
449 }
450 else {
451 char *source_buf = PyByteArray_AS_STRING(self);
452 char *result_buf = (char *)PyMem_Malloc(slicelength);
453 PyObject *result;
454
455 if (result_buf == NULL)
456 return PyErr_NoMemory();
457
458 for (cur = start, i = 0; i < slicelength;
459 cur += step, i++) {
460 result_buf[i] = source_buf[cur];
461 }
462 result = PyByteArray_FromStringAndSize(result_buf, slicelength);
463 PyMem_Free(result_buf);
464 return result;
465 }
466 }
467 else {
468 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
469 return NULL;
470 }
471}
472
473static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000474bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes44720832008-05-26 13:01:01 +0000475 PyObject *values)
476{
477 Py_ssize_t avail, needed;
478 void *bytes;
479 Py_buffer vbytes;
480 int res = 0;
481
482 vbytes.len = -1;
483 if (values == (PyObject *)self) {
484 /* Make a copy and call this function recursively */
485 int err;
486 values = PyByteArray_FromObject(values);
487 if (values == NULL)
488 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000489 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes44720832008-05-26 13:01:01 +0000490 Py_DECREF(values);
491 return err;
492 }
493 if (values == NULL) {
494 /* del b[lo:hi] */
495 bytes = NULL;
496 needed = 0;
497 }
498 else {
499 if (_getbuffer(values, &vbytes) < 0) {
500 PyErr_Format(PyExc_TypeError,
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000501 "can't set bytearray slice from %.100s",
Christian Heimes44720832008-05-26 13:01:01 +0000502 Py_TYPE(values)->tp_name);
503 return -1;
504 }
505 needed = vbytes.len;
506 bytes = vbytes.buf;
507 }
508
509 if (lo < 0)
510 lo = 0;
511 if (hi < lo)
512 hi = lo;
513 if (hi > Py_SIZE(self))
514 hi = Py_SIZE(self);
515
516 avail = hi - lo;
517 if (avail < 0)
518 lo = hi = avail = 0;
519
520 if (avail != needed) {
521 if (avail > needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000522 if (!_canresize(self)) {
523 res = -1;
524 goto finish;
525 }
Christian Heimes44720832008-05-26 13:01:01 +0000526 /*
527 0 lo hi old_size
528 | |<----avail----->|<-----tomove------>|
529 | |<-needed->|<-----tomove------>|
530 0 lo new_hi new_size
531 */
532 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
533 Py_SIZE(self) - hi);
534 }
535 /* XXX(nnorwitz): need to verify this can't overflow! */
536 if (PyByteArray_Resize((PyObject *)self,
537 Py_SIZE(self) + needed - avail) < 0) {
538 res = -1;
539 goto finish;
540 }
541 if (avail < needed) {
542 /*
543 0 lo hi old_size
544 | |<-avail->|<-----tomove------>|
545 | |<----needed---->|<-----tomove------>|
546 0 lo new_hi new_size
547 */
548 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
549 Py_SIZE(self) - lo - needed);
550 }
551 }
552
553 if (needed > 0)
554 memcpy(self->ob_bytes + lo, bytes, needed);
555
556
557 finish:
558 if (vbytes.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000559 PyBuffer_Release(&vbytes);
Christian Heimes44720832008-05-26 13:01:01 +0000560 return res;
561}
562
563static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000564bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes44720832008-05-26 13:01:01 +0000565{
566 int ival;
567
568 if (i < 0)
569 i += Py_SIZE(self);
570
571 if (i < 0 || i >= Py_SIZE(self)) {
572 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
573 return -1;
574 }
575
576 if (value == NULL)
Benjamin Petersond6720012009-04-18 15:31:34 +0000577 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes44720832008-05-26 13:01:01 +0000578
579 if (!_getbytevalue(value, &ival))
580 return -1;
581
582 self->ob_bytes[i] = ival;
583 return 0;
584}
585
586static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000587bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes44720832008-05-26 13:01:01 +0000588{
589 Py_ssize_t start, stop, step, slicelen, needed;
590 char *bytes;
591
Georg Brandl3e483f62008-07-16 22:57:41 +0000592 if (PyIndex_Check(index)) {
593 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000594
595 if (i == -1 && PyErr_Occurred())
596 return -1;
597
598 if (i < 0)
599 i += PyByteArray_GET_SIZE(self);
600
601 if (i < 0 || i >= Py_SIZE(self)) {
602 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
603 return -1;
604 }
605
606 if (values == NULL) {
607 /* Fall through to slice assignment */
608 start = i;
609 stop = i + 1;
610 step = 1;
611 slicelen = 1;
612 }
613 else {
Georg Brandl3e483f62008-07-16 22:57:41 +0000614 int ival;
615 if (!_getbytevalue(values, &ival))
Christian Heimes44720832008-05-26 13:01:01 +0000616 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000617 self->ob_bytes[i] = (char)ival;
618 return 0;
619 }
620 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000621 else if (PySlice_Check(index)) {
Serhiy Storchakae41390a2017-04-08 11:48:57 +0300622 if (_PySlice_Unpack((PySliceObject *)index, &start, &stop, &step) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +0000623 return -1;
624 }
Serhiy Storchakae41390a2017-04-08 11:48:57 +0300625 slicelen = _PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start,
626 &stop, step);
Christian Heimes44720832008-05-26 13:01:01 +0000627 }
628 else {
629 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
630 return -1;
631 }
632
633 if (values == NULL) {
634 bytes = NULL;
635 needed = 0;
636 }
637 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes146a5fe2012-11-03 23:07:59 +0100638 int err;
Ezio Melotti67dc4a82012-11-03 21:10:45 +0200639 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
640 PyErr_SetString(PyExc_TypeError,
641 "can assign only bytes, buffers, or iterables "
642 "of ints in range(0, 256)");
643 return -1;
644 }
Georg Brandl28dadd92011-02-25 10:50:32 +0000645 /* Make a copy and call this function recursively */
Christian Heimes44720832008-05-26 13:01:01 +0000646 values = PyByteArray_FromObject(values);
647 if (values == NULL)
648 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000649 err = bytearray_ass_subscript(self, index, values);
Christian Heimes44720832008-05-26 13:01:01 +0000650 Py_DECREF(values);
651 return err;
652 }
653 else {
654 assert(PyByteArray_Check(values));
655 bytes = ((PyByteArrayObject *)values)->ob_bytes;
656 needed = Py_SIZE(values);
657 }
658 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
659 if ((step < 0 && start < stop) ||
660 (step > 0 && start > stop))
661 stop = start;
662 if (step == 1) {
663 if (slicelen != needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000664 if (!_canresize(self))
665 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000666 if (slicelen > needed) {
667 /*
668 0 start stop old_size
669 | |<---slicelen--->|<-----tomove------>|
670 | |<-needed->|<-----tomove------>|
671 0 lo new_hi new_size
672 */
673 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
674 Py_SIZE(self) - stop);
675 }
676 if (PyByteArray_Resize((PyObject *)self,
677 Py_SIZE(self) + needed - slicelen) < 0)
678 return -1;
679 if (slicelen < needed) {
680 /*
681 0 lo hi old_size
682 | |<-avail->|<-----tomove------>|
683 | |<----needed---->|<-----tomove------>|
684 0 lo new_hi new_size
685 */
686 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
687 Py_SIZE(self) - start - needed);
688 }
689 }
690
691 if (needed > 0)
692 memcpy(self->ob_bytes + start, bytes, needed);
693
694 return 0;
695 }
696 else {
697 if (needed == 0) {
698 /* Delete slice */
Mark Dickinson36ecd672010-01-29 17:11:39 +0000699 size_t cur;
700 Py_ssize_t i;
Christian Heimes44720832008-05-26 13:01:01 +0000701
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000702 if (!_canresize(self))
703 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000704 if (step < 0) {
705 stop = start + 1;
706 start = stop + step * (slicelen - 1) - 1;
707 step = -step;
708 }
709 for (cur = start, i = 0;
710 i < slicelen; cur += step, i++) {
711 Py_ssize_t lim = step - 1;
712
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000713 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes44720832008-05-26 13:01:01 +0000714 lim = PyByteArray_GET_SIZE(self) - cur - 1;
715
716 memmove(self->ob_bytes + cur - i,
717 self->ob_bytes + cur + 1, lim);
718 }
719 /* Move the tail of the bytes, in one chunk */
720 cur = start + slicelen*step;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000721 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Christian Heimes44720832008-05-26 13:01:01 +0000722 memmove(self->ob_bytes + cur - slicelen,
723 self->ob_bytes + cur,
724 PyByteArray_GET_SIZE(self) - cur);
725 }
726 if (PyByteArray_Resize((PyObject *)self,
727 PyByteArray_GET_SIZE(self) - slicelen) < 0)
728 return -1;
729
730 return 0;
731 }
732 else {
733 /* Assign slice */
734 Py_ssize_t cur, i;
735
736 if (needed != slicelen) {
737 PyErr_Format(PyExc_ValueError,
738 "attempt to assign bytes of size %zd "
739 "to extended slice of size %zd",
740 needed, slicelen);
741 return -1;
742 }
743 for (cur = start, i = 0; i < slicelen; cur += step, i++)
744 self->ob_bytes[cur] = bytes[i];
745 return 0;
746 }
747 }
748}
749
750static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000751bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes44720832008-05-26 13:01:01 +0000752{
753 static char *kwlist[] = {"source", "encoding", "errors", 0};
754 PyObject *arg = NULL;
755 const char *encoding = NULL;
756 const char *errors = NULL;
757 Py_ssize_t count;
758 PyObject *it;
759 PyObject *(*iternext)(PyObject *);
760
761 if (Py_SIZE(self) != 0) {
762 /* Empty previous contents (yes, do this first of all!) */
763 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
764 return -1;
765 }
766
767 /* Parse arguments */
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000768 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes44720832008-05-26 13:01:01 +0000769 &arg, &encoding, &errors))
770 return -1;
771
772 /* Make a quick exit if no first argument */
773 if (arg == NULL) {
774 if (encoding != NULL || errors != NULL) {
775 PyErr_SetString(PyExc_TypeError,
776 "encoding or errors without sequence argument");
777 return -1;
778 }
779 return 0;
780 }
781
782 if (PyBytes_Check(arg)) {
783 PyObject *new, *encoded;
784 if (encoding != NULL) {
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300785 encoded = _PyCodec_EncodeText(arg, encoding, errors);
Christian Heimes44720832008-05-26 13:01:01 +0000786 if (encoded == NULL)
787 return -1;
788 assert(PyBytes_Check(encoded));
789 }
790 else {
791 encoded = arg;
792 Py_INCREF(arg);
793 }
Benjamin Petersond6720012009-04-18 15:31:34 +0000794 new = bytearray_iconcat(self, arg);
Christian Heimes44720832008-05-26 13:01:01 +0000795 Py_DECREF(encoded);
796 if (new == NULL)
797 return -1;
798 Py_DECREF(new);
799 return 0;
800 }
801
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000802#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +0000803 if (PyUnicode_Check(arg)) {
804 /* Encode via the codec registry */
805 PyObject *encoded, *new;
806 if (encoding == NULL) {
807 PyErr_SetString(PyExc_TypeError,
808 "unicode argument without an encoding");
809 return -1;
810 }
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300811 encoded = _PyCodec_EncodeText(arg, encoding, errors);
Christian Heimes44720832008-05-26 13:01:01 +0000812 if (encoded == NULL)
813 return -1;
814 assert(PyBytes_Check(encoded));
Benjamin Petersond6720012009-04-18 15:31:34 +0000815 new = bytearray_iconcat(self, encoded);
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 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000822#endif
Christian Heimes44720832008-05-26 13:01:01 +0000823
824 /* If it's not unicode, there can't be encoding or errors */
825 if (encoding != NULL || errors != NULL) {
826 PyErr_SetString(PyExc_TypeError,
827 "encoding or errors without a string argument");
828 return -1;
829 }
830
831 /* Is it an int? */
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000832 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
833 if (count == -1 && PyErr_Occurred()) {
834 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes44720832008-05-26 13:01:01 +0000835 return -1;
Benjamin Petersonae530c22010-04-16 22:52:44 +0000836 PyErr_Clear();
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000837 }
838 else if (count < 0) {
839 PyErr_SetString(PyExc_ValueError, "negative count");
840 return -1;
841 }
842 else {
Christian Heimes44720832008-05-26 13:01:01 +0000843 if (count > 0) {
844 if (PyByteArray_Resize((PyObject *)self, count))
845 return -1;
846 memset(self->ob_bytes, 0, count);
847 }
848 return 0;
849 }
850
851 /* Use the buffer API */
852 if (PyObject_CheckBuffer(arg)) {
853 Py_ssize_t size;
854 Py_buffer view;
855 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
856 return -1;
857 size = view.len;
858 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
859 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
860 goto fail;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000861 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000862 return 0;
863 fail:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000864 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000865 return -1;
866 }
867
868 /* XXX Optimize this if the arguments is a list, tuple */
869
870 /* Get the iterator */
871 it = PyObject_GetIter(arg);
872 if (it == NULL)
873 return -1;
874 iternext = *Py_TYPE(it)->tp_iternext;
875
876 /* Run the iterator to exhaustion */
877 for (;;) {
878 PyObject *item;
Georg Brandl3e758462008-07-16 23:10:05 +0000879 int rc, value;
Christian Heimes44720832008-05-26 13:01:01 +0000880
881 /* Get the next item */
882 item = iternext(it);
883 if (item == NULL) {
884 if (PyErr_Occurred()) {
885 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
886 goto error;
887 PyErr_Clear();
888 }
889 break;
890 }
891
892 /* Interpret it as an int (__index__) */
Georg Brandl3e758462008-07-16 23:10:05 +0000893 rc = _getbytevalue(item, &value);
Christian Heimes44720832008-05-26 13:01:01 +0000894 Py_DECREF(item);
Georg Brandl3e758462008-07-16 23:10:05 +0000895 if (!rc)
Christian Heimes44720832008-05-26 13:01:01 +0000896 goto error;
897
Christian Heimes44720832008-05-26 13:01:01 +0000898 /* Append the byte */
Serhiy Storchakaab766352015-06-29 21:13:54 +0300899 if (Py_SIZE(self) + 1 < self->ob_alloc) {
Christian Heimes44720832008-05-26 13:01:01 +0000900 Py_SIZE(self)++;
Serhiy Storchakaab766352015-06-29 21:13:54 +0300901 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
902 }
Christian Heimes44720832008-05-26 13:01:01 +0000903 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
904 goto error;
905 self->ob_bytes[Py_SIZE(self)-1] = value;
906 }
907
908 /* Clean up and return success */
909 Py_DECREF(it);
910 return 0;
911
912 error:
913 /* Error handling when it != NULL */
914 Py_DECREF(it);
915 return -1;
916}
917
918/* Mostly copied from string_repr, but without the
919 "smart quote" functionality. */
920static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000921bytearray_repr(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000922{
923 static const char *hexdigits = "0123456789abcdef";
924 const char *quote_prefix = "bytearray(b";
925 const char *quote_postfix = ")";
926 Py_ssize_t length = Py_SIZE(self);
927 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000928 size_t newsize;
Christian Heimes44720832008-05-26 13:01:01 +0000929 PyObject *v;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000930 if (length > (PY_SSIZE_T_MAX - 14) / 4) {
Christian Heimes44720832008-05-26 13:01:01 +0000931 PyErr_SetString(PyExc_OverflowError,
932 "bytearray object is too large to make repr");
933 return NULL;
934 }
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000935 newsize = 14 + 4 * length;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000936 v = PyString_FromStringAndSize(NULL, newsize);
Christian Heimes44720832008-05-26 13:01:01 +0000937 if (v == NULL) {
938 return NULL;
939 }
940 else {
941 register Py_ssize_t i;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000942 register char c;
943 register char *p;
Christian Heimes44720832008-05-26 13:01:01 +0000944 int quote;
945
946 /* Figure out which quote to use; single is preferred */
947 quote = '\'';
948 {
949 char *test, *start;
950 start = PyByteArray_AS_STRING(self);
951 for (test = start; test < start+length; ++test) {
952 if (*test == '"') {
953 quote = '\''; /* back to single */
954 goto decided;
955 }
956 else if (*test == '\'')
957 quote = '"';
958 }
959 decided:
960 ;
961 }
962
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000963 p = PyString_AS_STRING(v);
Christian Heimes44720832008-05-26 13:01:01 +0000964 while (*quote_prefix)
965 *p++ = *quote_prefix++;
966 *p++ = quote;
967
968 for (i = 0; i < length; i++) {
969 /* There's at least enough room for a hex escape
970 and a closing quote. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000971 assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
Christian Heimes44720832008-05-26 13:01:01 +0000972 c = self->ob_bytes[i];
973 if (c == '\'' || c == '\\')
974 *p++ = '\\', *p++ = c;
975 else if (c == '\t')
976 *p++ = '\\', *p++ = 't';
977 else if (c == '\n')
978 *p++ = '\\', *p++ = 'n';
979 else if (c == '\r')
980 *p++ = '\\', *p++ = 'r';
981 else if (c == 0)
982 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
983 else if (c < ' ' || c >= 0x7f) {
984 *p++ = '\\';
985 *p++ = 'x';
986 *p++ = hexdigits[(c & 0xf0) >> 4];
987 *p++ = hexdigits[c & 0xf];
988 }
989 else
990 *p++ = c;
991 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000992 assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
Christian Heimes44720832008-05-26 13:01:01 +0000993 *p++ = quote;
994 while (*quote_postfix) {
995 *p++ = *quote_postfix++;
996 }
997 *p = '\0';
Kristján Valur Jónssonbe580f22014-04-25 09:51:21 +0000998 /* v is cleared on error */
999 (void)_PyString_Resize(&v, (p - PyString_AS_STRING(v)));
Christian Heimes44720832008-05-26 13:01:01 +00001000 return v;
1001 }
1002}
1003
1004static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001005bytearray_str(PyObject *op)
Christian Heimes44720832008-05-26 13:01:01 +00001006{
1007#if 0
1008 if (Py_BytesWarningFlag) {
1009 if (PyErr_WarnEx(PyExc_BytesWarning,
1010 "str() on a bytearray instance", 1))
1011 return NULL;
1012 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001013 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes44720832008-05-26 13:01:01 +00001014#endif
1015 return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
1016}
1017
1018static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001019bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes44720832008-05-26 13:01:01 +00001020{
1021 Py_ssize_t self_size, other_size;
1022 Py_buffer self_bytes, other_bytes;
1023 PyObject *res;
1024 Py_ssize_t minsize;
Serhiy Storchaka5127ed72015-05-30 17:45:12 +03001025 int cmp, rc;
Christian Heimes44720832008-05-26 13:01:01 +00001026
1027 /* Bytes can be compared to anything that supports the (binary)
1028 buffer API. Except that a comparison with Unicode is always an
1029 error, even if the comparison is for equality. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001030#ifdef Py_USING_UNICODE
Serhiy Storchaka5127ed72015-05-30 17:45:12 +03001031 rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type);
1032 if (!rc)
1033 rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type);
1034 if (rc < 0)
1035 return NULL;
1036 if (rc) {
Christian Heimes44720832008-05-26 13:01:01 +00001037 if (Py_BytesWarningFlag && op == Py_EQ) {
1038 if (PyErr_WarnEx(PyExc_BytesWarning,
Ezio Melottid2342082010-01-14 11:34:10 +00001039 "Comparison between bytearray and string", 1))
Christian Heimes44720832008-05-26 13:01:01 +00001040 return NULL;
1041 }
1042
1043 Py_INCREF(Py_NotImplemented);
1044 return Py_NotImplemented;
1045 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001046#endif
Christian Heimes44720832008-05-26 13:01:01 +00001047
1048 self_size = _getbuffer(self, &self_bytes);
1049 if (self_size < 0) {
1050 PyErr_Clear();
1051 Py_INCREF(Py_NotImplemented);
1052 return Py_NotImplemented;
1053 }
1054
1055 other_size = _getbuffer(other, &other_bytes);
1056 if (other_size < 0) {
1057 PyErr_Clear();
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001058 PyBuffer_Release(&self_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001059 Py_INCREF(Py_NotImplemented);
1060 return Py_NotImplemented;
1061 }
1062
1063 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1064 /* Shortcut: if the lengths differ, the objects differ */
1065 cmp = (op == Py_NE);
1066 }
1067 else {
1068 minsize = self_size;
1069 if (other_size < minsize)
1070 minsize = other_size;
1071
1072 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1073 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1074
1075 if (cmp == 0) {
1076 if (self_size < other_size)
1077 cmp = -1;
1078 else if (self_size > other_size)
1079 cmp = 1;
1080 }
1081
1082 switch (op) {
1083 case Py_LT: cmp = cmp < 0; break;
1084 case Py_LE: cmp = cmp <= 0; break;
1085 case Py_EQ: cmp = cmp == 0; break;
1086 case Py_NE: cmp = cmp != 0; break;
1087 case Py_GT: cmp = cmp > 0; break;
1088 case Py_GE: cmp = cmp >= 0; break;
1089 }
1090 }
1091
1092 res = cmp ? Py_True : Py_False;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001093 PyBuffer_Release(&self_bytes);
1094 PyBuffer_Release(&other_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001095 Py_INCREF(res);
1096 return res;
1097}
1098
1099static void
Benjamin Petersond6720012009-04-18 15:31:34 +00001100bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00001101{
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001102 if (self->ob_exports > 0) {
1103 PyErr_SetString(PyExc_SystemError,
Georg Brandl517cfdc2009-04-05 13:16:35 +00001104 "deallocated bytearray object has exported buffers");
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001105 PyErr_Print();
1106 }
Christian Heimes44720832008-05-26 13:01:01 +00001107 if (self->ob_bytes != 0) {
1108 PyMem_Free(self->ob_bytes);
1109 }
1110 Py_TYPE(self)->tp_free((PyObject *)self);
1111}
1112
1113
1114/* -------------------------------------------------------------------- */
1115/* Methods */
1116
1117#define STRINGLIB_CHAR char
Christian Heimes44720832008-05-26 13:01:01 +00001118#define STRINGLIB_LEN PyByteArray_GET_SIZE
1119#define STRINGLIB_STR PyByteArray_AS_STRING
1120#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrou64672132010-01-13 07:55:48 +00001121#define STRINGLIB_ISSPACE Py_ISSPACE
1122#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes44720832008-05-26 13:01:01 +00001123#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1124#define STRINGLIB_MUTABLE 1
1125
1126#include "stringlib/fastsearch.h"
1127#include "stringlib/count.h"
1128#include "stringlib/find.h"
1129#include "stringlib/partition.h"
Antoine Pitrou64672132010-01-13 07:55:48 +00001130#include "stringlib/split.h"
Christian Heimes44720832008-05-26 13:01:01 +00001131#include "stringlib/ctype.h"
1132#include "stringlib/transmogrify.h"
1133
1134
1135/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1136were copied from the old char* style string object. */
1137
Antoine Pitrou64672132010-01-13 07:55:48 +00001138/* helper macro to fixup start/end slice values */
1139#define ADJUST_INDICES(start, end, len) \
1140 if (end > len) \
1141 end = len; \
1142 else if (end < 0) { \
1143 end += len; \
1144 if (end < 0) \
1145 end = 0; \
1146 } \
1147 if (start < 0) { \
1148 start += len; \
1149 if (start < 0) \
1150 start = 0; \
1151 }
Christian Heimes44720832008-05-26 13:01:01 +00001152
1153Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Petersond6720012009-04-18 15:31:34 +00001154bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes44720832008-05-26 13:01:01 +00001155{
1156 PyObject *subobj;
1157 Py_buffer subbuf;
1158 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1159 Py_ssize_t res;
1160
Jesus Cea44e81682011-04-20 16:39:15 +02001161 if (!stringlib_parse_args_finds("find/rfind/index/rindex",
1162 args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001163 return -2;
1164 if (_getbuffer(subobj, &subbuf) < 0)
1165 return -2;
1166 if (dir > 0)
1167 res = stringlib_find_slice(
1168 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1169 subbuf.buf, subbuf.len, start, end);
1170 else
1171 res = stringlib_rfind_slice(
1172 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1173 subbuf.buf, subbuf.len, start, end);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001174 PyBuffer_Release(&subbuf);
Christian Heimes44720832008-05-26 13:01:01 +00001175 return res;
1176}
1177
1178PyDoc_STRVAR(find__doc__,
1179"B.find(sub [,start [,end]]) -> int\n\
1180\n\
1181Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran5e3a19d2011-07-27 23:36:51 +08001182such that sub is contained within B[start,end]. Optional\n\
Christian Heimes44720832008-05-26 13:01:01 +00001183arguments start and end are interpreted as in slice notation.\n\
1184\n\
1185Return -1 on failure.");
1186
1187static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001188bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001189{
Benjamin Petersond6720012009-04-18 15:31:34 +00001190 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001191 if (result == -2)
1192 return NULL;
1193 return PyInt_FromSsize_t(result);
1194}
1195
1196PyDoc_STRVAR(count__doc__,
1197"B.count(sub [,start [,end]]) -> int\n\
1198\n\
1199Return the number of non-overlapping occurrences of subsection sub in\n\
1200bytes B[start:end]. Optional arguments start and end are interpreted\n\
1201as in slice notation.");
1202
1203static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001204bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001205{
1206 PyObject *sub_obj;
1207 const char *str = PyByteArray_AS_STRING(self);
1208 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1209 Py_buffer vsub;
1210 PyObject *count_obj;
1211
Jesus Cea44e81682011-04-20 16:39:15 +02001212 if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001213 return NULL;
1214
1215 if (_getbuffer(sub_obj, &vsub) < 0)
1216 return NULL;
1217
Antoine Pitrou64672132010-01-13 07:55:48 +00001218 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes44720832008-05-26 13:01:01 +00001219
1220 count_obj = PyInt_FromSsize_t(
Antoine Pitrou64672132010-01-13 07:55:48 +00001221 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes44720832008-05-26 13:01:01 +00001222 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001223 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00001224 return count_obj;
1225}
1226
1227
1228PyDoc_STRVAR(index__doc__,
1229"B.index(sub [,start [,end]]) -> int\n\
1230\n\
1231Like B.find() but raise ValueError when the subsection is not found.");
1232
1233static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001234bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001235{
Benjamin Petersond6720012009-04-18 15:31:34 +00001236 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001237 if (result == -2)
1238 return NULL;
1239 if (result == -1) {
1240 PyErr_SetString(PyExc_ValueError,
1241 "subsection not found");
1242 return NULL;
1243 }
1244 return PyInt_FromSsize_t(result);
1245}
1246
1247
1248PyDoc_STRVAR(rfind__doc__,
1249"B.rfind(sub [,start [,end]]) -> int\n\
1250\n\
1251Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran5e3a19d2011-07-27 23:36:51 +08001252such that sub is contained within B[start,end]. Optional\n\
Christian Heimes44720832008-05-26 13:01:01 +00001253arguments start and end are interpreted as in slice notation.\n\
1254\n\
1255Return -1 on failure.");
1256
1257static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001258bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001259{
Benjamin Petersond6720012009-04-18 15:31:34 +00001260 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001261 if (result == -2)
1262 return NULL;
1263 return PyInt_FromSsize_t(result);
1264}
1265
1266
1267PyDoc_STRVAR(rindex__doc__,
1268"B.rindex(sub [,start [,end]]) -> int\n\
1269\n\
1270Like B.rfind() but raise ValueError when the subsection is not found.");
1271
1272static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001273bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001274{
Benjamin Petersond6720012009-04-18 15:31:34 +00001275 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001276 if (result == -2)
1277 return NULL;
1278 if (result == -1) {
1279 PyErr_SetString(PyExc_ValueError,
1280 "subsection not found");
1281 return NULL;
1282 }
1283 return PyInt_FromSsize_t(result);
1284}
1285
1286
1287static int
Benjamin Petersond6720012009-04-18 15:31:34 +00001288bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00001289{
1290 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1291 if (ival == -1 && PyErr_Occurred()) {
1292 Py_buffer varg;
1293 int pos;
1294 PyErr_Clear();
1295 if (_getbuffer(arg, &varg) < 0)
1296 return -1;
1297 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1298 varg.buf, varg.len, 0);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001299 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00001300 return pos >= 0;
1301 }
1302 if (ival < 0 || ival >= 256) {
1303 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1304 return -1;
1305 }
1306
1307 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1308}
1309
1310
1311/* Matches the end (direction >= 0) or start (direction < 0) of self
1312 * against substr, using the start and end arguments. Returns
1313 * -1 on error, 0 if not found and 1 if found.
1314 */
1315Py_LOCAL(int)
Benjamin Petersond6720012009-04-18 15:31:34 +00001316_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes44720832008-05-26 13:01:01 +00001317 Py_ssize_t end, int direction)
1318{
1319 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1320 const char* str;
1321 Py_buffer vsubstr;
1322 int rv = 0;
1323
1324 str = PyByteArray_AS_STRING(self);
1325
1326 if (_getbuffer(substr, &vsubstr) < 0)
1327 return -1;
1328
Antoine Pitrou64672132010-01-13 07:55:48 +00001329 ADJUST_INDICES(start, end, len);
Christian Heimes44720832008-05-26 13:01:01 +00001330
1331 if (direction < 0) {
1332 /* startswith */
1333 if (start+vsubstr.len > len) {
1334 goto done;
1335 }
1336 } else {
1337 /* endswith */
1338 if (end-start < vsubstr.len || start > len) {
1339 goto done;
1340 }
1341
1342 if (end-vsubstr.len > start)
1343 start = end - vsubstr.len;
1344 }
1345 if (end-start >= vsubstr.len)
1346 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1347
1348done:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001349 PyBuffer_Release(&vsubstr);
Christian Heimes44720832008-05-26 13:01:01 +00001350 return rv;
1351}
1352
1353
1354PyDoc_STRVAR(startswith__doc__,
1355"B.startswith(prefix [,start [,end]]) -> bool\n\
1356\n\
1357Return True if B starts with the specified prefix, False otherwise.\n\
1358With optional start, test B beginning at that position.\n\
1359With optional end, stop comparing B at that position.\n\
1360prefix can also be a tuple of strings to try.");
1361
1362static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001363bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001364{
1365 Py_ssize_t start = 0;
1366 Py_ssize_t end = PY_SSIZE_T_MAX;
1367 PyObject *subobj;
1368 int result;
1369
Jesus Cea44e81682011-04-20 16:39:15 +02001370 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001371 return NULL;
1372 if (PyTuple_Check(subobj)) {
1373 Py_ssize_t i;
1374 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001375 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001376 PyTuple_GET_ITEM(subobj, i),
1377 start, end, -1);
1378 if (result == -1)
1379 return NULL;
1380 else if (result) {
1381 Py_RETURN_TRUE;
1382 }
1383 }
1384 Py_RETURN_FALSE;
1385 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001386 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001387 if (result == -1)
1388 return NULL;
1389 else
1390 return PyBool_FromLong(result);
1391}
1392
1393PyDoc_STRVAR(endswith__doc__,
1394"B.endswith(suffix [,start [,end]]) -> bool\n\
1395\n\
1396Return True if B ends with the specified suffix, False otherwise.\n\
1397With optional start, test B beginning at that position.\n\
1398With optional end, stop comparing B at that position.\n\
1399suffix can also be a tuple of strings to try.");
1400
1401static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001402bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001403{
1404 Py_ssize_t start = 0;
1405 Py_ssize_t end = PY_SSIZE_T_MAX;
1406 PyObject *subobj;
1407 int result;
1408
Jesus Cea44e81682011-04-20 16:39:15 +02001409 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001410 return NULL;
1411 if (PyTuple_Check(subobj)) {
1412 Py_ssize_t i;
1413 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001414 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001415 PyTuple_GET_ITEM(subobj, i),
1416 start, end, +1);
1417 if (result == -1)
1418 return NULL;
1419 else if (result) {
1420 Py_RETURN_TRUE;
1421 }
1422 }
1423 Py_RETURN_FALSE;
1424 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001425 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001426 if (result == -1)
1427 return NULL;
1428 else
1429 return PyBool_FromLong(result);
1430}
1431
1432
1433PyDoc_STRVAR(translate__doc__,
1434"B.translate(table[, deletechars]) -> bytearray\n\
1435\n\
1436Return a copy of B, where all characters occurring in the\n\
1437optional argument deletechars are removed, and the remaining\n\
1438characters have been mapped through the given translation\n\
1439table, which must be a bytes object of length 256.");
1440
1441static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001442bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001443{
1444 register char *input, *output;
1445 register const char *table;
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001446 register Py_ssize_t i, c;
Christian Heimes44720832008-05-26 13:01:01 +00001447 PyObject *input_obj = (PyObject*)self;
1448 const char *output_start;
1449 Py_ssize_t inlen;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001450 PyObject *result = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001451 int trans_table[256];
Georg Brandl6425a2f2008-12-28 11:54:53 +00001452 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001453 Py_buffer vtable, vdel;
1454
1455 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1456 &tableobj, &delobj))
1457 return NULL;
1458
Georg Brandl6425a2f2008-12-28 11:54:53 +00001459 if (tableobj == Py_None) {
1460 table = NULL;
1461 tableobj = NULL;
1462 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00001463 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001464 } else {
1465 if (vtable.len != 256) {
1466 PyErr_SetString(PyExc_ValueError,
1467 "translation table must be 256 characters long");
Georg Brandlec812ca2009-07-22 11:57:15 +00001468 PyBuffer_Release(&vtable);
1469 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001470 }
1471 table = (const char*)vtable.buf;
Christian Heimes44720832008-05-26 13:01:01 +00001472 }
1473
1474 if (delobj != NULL) {
1475 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandlec812ca2009-07-22 11:57:15 +00001476 if (tableobj != NULL)
1477 PyBuffer_Release(&vtable);
1478 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001479 }
1480 }
1481 else {
1482 vdel.buf = NULL;
1483 vdel.len = 0;
1484 }
1485
Christian Heimes44720832008-05-26 13:01:01 +00001486 inlen = PyByteArray_GET_SIZE(input_obj);
1487 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1488 if (result == NULL)
1489 goto done;
1490 output_start = output = PyByteArray_AsString(result);
1491 input = PyByteArray_AS_STRING(input_obj);
1492
Georg Brandl6425a2f2008-12-28 11:54:53 +00001493 if (vdel.len == 0 && table != NULL) {
Christian Heimes44720832008-05-26 13:01:01 +00001494 /* If no deletions are required, use faster code */
1495 for (i = inlen; --i >= 0; ) {
1496 c = Py_CHARMASK(*input++);
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001497 *output++ = table[c];
Christian Heimes44720832008-05-26 13:01:01 +00001498 }
Christian Heimes44720832008-05-26 13:01:01 +00001499 goto done;
1500 }
Georg Brandl6425a2f2008-12-28 11:54:53 +00001501
1502 if (table == NULL) {
1503 for (i = 0; i < 256; i++)
1504 trans_table[i] = Py_CHARMASK(i);
1505 } else {
1506 for (i = 0; i < 256; i++)
1507 trans_table[i] = Py_CHARMASK(table[i]);
1508 }
Christian Heimes44720832008-05-26 13:01:01 +00001509
1510 for (i = 0; i < vdel.len; i++)
1511 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1512
1513 for (i = inlen; --i >= 0; ) {
1514 c = Py_CHARMASK(*input++);
1515 if (trans_table[c] != -1)
1516 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1517 continue;
Christian Heimes44720832008-05-26 13:01:01 +00001518 }
1519 /* Fix the size of the resulting string */
1520 if (inlen > 0)
1521 PyByteArray_Resize(result, output - output_start);
1522
1523done:
Georg Brandl6425a2f2008-12-28 11:54:53 +00001524 if (tableobj != NULL)
1525 PyBuffer_Release(&vtable);
Christian Heimes44720832008-05-26 13:01:01 +00001526 if (delobj != NULL)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001527 PyBuffer_Release(&vdel);
Christian Heimes44720832008-05-26 13:01:01 +00001528 return result;
1529}
1530
1531
Christian Heimes44720832008-05-26 13:01:01 +00001532/* find and count characters and substrings */
1533
1534#define findchar(target, target_len, c) \
1535 ((char *)memchr((const void *)(target), c, target_len))
1536
Christian Heimes44720832008-05-26 13:01:01 +00001537
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001538/* Bytes ops must return a string, create a copy */
Christian Heimes44720832008-05-26 13:01:01 +00001539Py_LOCAL(PyByteArrayObject *)
1540return_self(PyByteArrayObject *self)
1541{
Christian Heimes44720832008-05-26 13:01:01 +00001542 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1543 PyByteArray_AS_STRING(self),
1544 PyByteArray_GET_SIZE(self));
1545}
1546
1547Py_LOCAL_INLINE(Py_ssize_t)
1548countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1549{
1550 Py_ssize_t count=0;
1551 const char *start=target;
1552 const char *end=target+target_len;
1553
1554 while ( (start=findchar(start, end-start, c)) != NULL ) {
1555 count++;
1556 if (count >= maxcount)
1557 break;
1558 start += 1;
1559 }
1560 return count;
1561}
1562
Christian Heimes44720832008-05-26 13:01:01 +00001563
1564/* Algorithms for different cases of string replacement */
1565
1566/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1567Py_LOCAL(PyByteArrayObject *)
1568replace_interleave(PyByteArrayObject *self,
1569 const char *to_s, Py_ssize_t to_len,
1570 Py_ssize_t maxcount)
1571{
1572 char *self_s, *result_s;
1573 Py_ssize_t self_len, result_len;
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001574 Py_ssize_t count, i;
Christian Heimes44720832008-05-26 13:01:01 +00001575 PyByteArrayObject *result;
1576
1577 self_len = PyByteArray_GET_SIZE(self);
1578
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001579 /* 1 at the end plus 1 after every character;
1580 count = min(maxcount, self_len + 1) */
1581 if (maxcount <= self_len) {
Christian Heimes44720832008-05-26 13:01:01 +00001582 count = maxcount;
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001583 }
1584 else {
1585 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1586 count = self_len + 1;
1587 }
Christian Heimes44720832008-05-26 13:01:01 +00001588
1589 /* Check for overflow */
1590 /* result_len = count * to_len + self_len; */
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001591 assert(count > 0);
1592 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes44720832008-05-26 13:01:01 +00001593 PyErr_SetString(PyExc_OverflowError,
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001594 "replace bytes is too long");
Christian Heimes44720832008-05-26 13:01:01 +00001595 return NULL;
1596 }
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001597 result_len = count * to_len + self_len;
Christian Heimes44720832008-05-26 13:01:01 +00001598 if (! (result = (PyByteArrayObject *)
1599 PyByteArray_FromStringAndSize(NULL, result_len)) )
1600 return NULL;
1601
1602 self_s = PyByteArray_AS_STRING(self);
1603 result_s = PyByteArray_AS_STRING(result);
1604
1605 /* TODO: special case single character, which doesn't need memcpy */
1606
1607 /* Lay the first one down (guaranteed this will occur) */
1608 Py_MEMCPY(result_s, to_s, to_len);
1609 result_s += to_len;
1610 count -= 1;
1611
1612 for (i=0; i<count; i++) {
1613 *result_s++ = *self_s++;
1614 Py_MEMCPY(result_s, to_s, to_len);
1615 result_s += to_len;
1616 }
1617
1618 /* Copy the rest of the original string */
1619 Py_MEMCPY(result_s, self_s, self_len-i);
1620
1621 return result;
1622}
1623
1624/* Special case for deleting a single character */
1625/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1626Py_LOCAL(PyByteArrayObject *)
1627replace_delete_single_character(PyByteArrayObject *self,
1628 char from_c, Py_ssize_t maxcount)
1629{
1630 char *self_s, *result_s;
1631 char *start, *next, *end;
1632 Py_ssize_t self_len, result_len;
1633 Py_ssize_t count;
1634 PyByteArrayObject *result;
1635
1636 self_len = PyByteArray_GET_SIZE(self);
1637 self_s = PyByteArray_AS_STRING(self);
1638
1639 count = countchar(self_s, self_len, from_c, maxcount);
1640 if (count == 0) {
1641 return return_self(self);
1642 }
1643
1644 result_len = self_len - count; /* from_len == 1 */
1645 assert(result_len>=0);
1646
1647 if ( (result = (PyByteArrayObject *)
1648 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1649 return NULL;
1650 result_s = PyByteArray_AS_STRING(result);
1651
1652 start = self_s;
1653 end = self_s + self_len;
1654 while (count-- > 0) {
1655 next = findchar(start, end-start, from_c);
1656 if (next == NULL)
1657 break;
1658 Py_MEMCPY(result_s, start, next-start);
1659 result_s += (next-start);
1660 start = next+1;
1661 }
1662 Py_MEMCPY(result_s, start, end-start);
1663
1664 return result;
1665}
1666
1667/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1668
1669Py_LOCAL(PyByteArrayObject *)
1670replace_delete_substring(PyByteArrayObject *self,
1671 const char *from_s, Py_ssize_t from_len,
1672 Py_ssize_t maxcount)
1673{
1674 char *self_s, *result_s;
1675 char *start, *next, *end;
1676 Py_ssize_t self_len, result_len;
1677 Py_ssize_t count, offset;
1678 PyByteArrayObject *result;
1679
1680 self_len = PyByteArray_GET_SIZE(self);
1681 self_s = PyByteArray_AS_STRING(self);
1682
Antoine Pitrou64672132010-01-13 07:55:48 +00001683 count = stringlib_count(self_s, self_len,
1684 from_s, from_len,
1685 maxcount);
Christian Heimes44720832008-05-26 13:01:01 +00001686
1687 if (count == 0) {
1688 /* no matches */
1689 return return_self(self);
1690 }
1691
1692 result_len = self_len - (count * from_len);
1693 assert (result_len>=0);
1694
1695 if ( (result = (PyByteArrayObject *)
1696 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1697 return NULL;
1698
1699 result_s = PyByteArray_AS_STRING(result);
1700
1701 start = self_s;
1702 end = self_s + self_len;
1703 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001704 offset = stringlib_find(start, end-start,
1705 from_s, from_len,
1706 0);
Christian Heimes44720832008-05-26 13:01:01 +00001707 if (offset == -1)
1708 break;
1709 next = start + offset;
1710
1711 Py_MEMCPY(result_s, start, next-start);
1712
1713 result_s += (next-start);
1714 start = next+from_len;
1715 }
1716 Py_MEMCPY(result_s, start, end-start);
1717 return result;
1718}
1719
1720/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1721Py_LOCAL(PyByteArrayObject *)
1722replace_single_character_in_place(PyByteArrayObject *self,
1723 char from_c, char to_c,
1724 Py_ssize_t maxcount)
1725{
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001726 char *self_s, *result_s, *start, *end, *next;
1727 Py_ssize_t self_len;
1728 PyByteArrayObject *result;
Christian Heimes44720832008-05-26 13:01:01 +00001729
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001730 /* The result string will be the same size */
1731 self_s = PyByteArray_AS_STRING(self);
1732 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes44720832008-05-26 13:01:01 +00001733
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001734 next = findchar(self_s, self_len, from_c);
Christian Heimes44720832008-05-26 13:01:01 +00001735
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001736 if (next == NULL) {
1737 /* No matches; return the original bytes */
1738 return return_self(self);
1739 }
Christian Heimes44720832008-05-26 13:01:01 +00001740
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001741 /* Need to make a new bytes */
1742 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1743 if (result == NULL)
1744 return NULL;
1745 result_s = PyByteArray_AS_STRING(result);
1746 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes44720832008-05-26 13:01:01 +00001747
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001748 /* change everything in-place, starting with this one */
1749 start = result_s + (next-self_s);
1750 *start = to_c;
1751 start++;
1752 end = result_s + self_len;
Christian Heimes44720832008-05-26 13:01:01 +00001753
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001754 while (--maxcount > 0) {
1755 next = findchar(start, end-start, from_c);
1756 if (next == NULL)
1757 break;
1758 *next = to_c;
1759 start = next+1;
1760 }
Christian Heimes44720832008-05-26 13:01:01 +00001761
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001762 return result;
Christian Heimes44720832008-05-26 13:01:01 +00001763}
1764
1765/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1766Py_LOCAL(PyByteArrayObject *)
1767replace_substring_in_place(PyByteArrayObject *self,
1768 const char *from_s, Py_ssize_t from_len,
1769 const char *to_s, Py_ssize_t to_len,
1770 Py_ssize_t maxcount)
1771{
1772 char *result_s, *start, *end;
1773 char *self_s;
1774 Py_ssize_t self_len, offset;
1775 PyByteArrayObject *result;
1776
1777 /* The result bytes will be the same size */
1778
1779 self_s = PyByteArray_AS_STRING(self);
1780 self_len = PyByteArray_GET_SIZE(self);
1781
Antoine Pitrou64672132010-01-13 07:55:48 +00001782 offset = stringlib_find(self_s, self_len,
1783 from_s, from_len,
1784 0);
Christian Heimes44720832008-05-26 13:01:01 +00001785 if (offset == -1) {
1786 /* No matches; return the original bytes */
1787 return return_self(self);
1788 }
1789
1790 /* Need to make a new bytes */
1791 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1792 if (result == NULL)
1793 return NULL;
1794 result_s = PyByteArray_AS_STRING(result);
1795 Py_MEMCPY(result_s, self_s, self_len);
1796
1797 /* change everything in-place, starting with this one */
1798 start = result_s + offset;
1799 Py_MEMCPY(start, to_s, from_len);
1800 start += from_len;
1801 end = result_s + self_len;
1802
1803 while ( --maxcount > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001804 offset = stringlib_find(start, end-start,
1805 from_s, from_len,
1806 0);
Christian Heimes44720832008-05-26 13:01:01 +00001807 if (offset==-1)
1808 break;
1809 Py_MEMCPY(start+offset, to_s, from_len);
1810 start += offset+from_len;
1811 }
1812
1813 return result;
1814}
1815
1816/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1817Py_LOCAL(PyByteArrayObject *)
1818replace_single_character(PyByteArrayObject *self,
1819 char from_c,
1820 const char *to_s, Py_ssize_t to_len,
1821 Py_ssize_t maxcount)
1822{
1823 char *self_s, *result_s;
1824 char *start, *next, *end;
1825 Py_ssize_t self_len, result_len;
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001826 Py_ssize_t count;
Christian Heimes44720832008-05-26 13:01:01 +00001827 PyByteArrayObject *result;
1828
1829 self_s = PyByteArray_AS_STRING(self);
1830 self_len = PyByteArray_GET_SIZE(self);
1831
1832 count = countchar(self_s, self_len, from_c, maxcount);
1833 if (count == 0) {
1834 /* no matches, return unchanged */
1835 return return_self(self);
1836 }
1837
1838 /* use the difference between current and new, hence the "-1" */
1839 /* result_len = self_len + count * (to_len-1) */
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001840 assert(count > 0);
1841 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes44720832008-05-26 13:01:01 +00001842 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1843 return NULL;
1844 }
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001845 result_len = self_len + count * (to_len - 1);
Christian Heimes44720832008-05-26 13:01:01 +00001846
1847 if ( (result = (PyByteArrayObject *)
1848 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1849 return NULL;
1850 result_s = PyByteArray_AS_STRING(result);
1851
1852 start = self_s;
1853 end = self_s + self_len;
1854 while (count-- > 0) {
1855 next = findchar(start, end-start, from_c);
1856 if (next == NULL)
1857 break;
1858
1859 if (next == start) {
1860 /* replace with the 'to' */
1861 Py_MEMCPY(result_s, to_s, to_len);
1862 result_s += to_len;
1863 start += 1;
1864 } else {
1865 /* copy the unchanged old then the 'to' */
1866 Py_MEMCPY(result_s, start, next-start);
1867 result_s += (next-start);
1868 Py_MEMCPY(result_s, to_s, to_len);
1869 result_s += to_len;
1870 start = next+1;
1871 }
1872 }
1873 /* Copy the remainder of the remaining bytes */
1874 Py_MEMCPY(result_s, start, end-start);
1875
1876 return result;
1877}
1878
1879/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1880Py_LOCAL(PyByteArrayObject *)
1881replace_substring(PyByteArrayObject *self,
1882 const char *from_s, Py_ssize_t from_len,
1883 const char *to_s, Py_ssize_t to_len,
1884 Py_ssize_t maxcount)
1885{
1886 char *self_s, *result_s;
1887 char *start, *next, *end;
1888 Py_ssize_t self_len, result_len;
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001889 Py_ssize_t count, offset;
Christian Heimes44720832008-05-26 13:01:01 +00001890 PyByteArrayObject *result;
1891
1892 self_s = PyByteArray_AS_STRING(self);
1893 self_len = PyByteArray_GET_SIZE(self);
1894
Antoine Pitrou64672132010-01-13 07:55:48 +00001895 count = stringlib_count(self_s, self_len,
1896 from_s, from_len,
1897 maxcount);
1898
Christian Heimes44720832008-05-26 13:01:01 +00001899 if (count == 0) {
1900 /* no matches, return unchanged */
1901 return return_self(self);
1902 }
1903
1904 /* Check for overflow */
1905 /* result_len = self_len + count * (to_len-from_len) */
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001906 assert(count > 0);
1907 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes44720832008-05-26 13:01:01 +00001908 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1909 return NULL;
1910 }
Xiang Zhang7bdb5162017-01-09 11:13:20 +08001911 result_len = self_len + count * (to_len - from_len);
Christian Heimes44720832008-05-26 13:01:01 +00001912
1913 if ( (result = (PyByteArrayObject *)
1914 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1915 return NULL;
1916 result_s = PyByteArray_AS_STRING(result);
1917
1918 start = self_s;
1919 end = self_s + self_len;
1920 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001921 offset = stringlib_find(start, end-start,
1922 from_s, from_len,
1923 0);
Christian Heimes44720832008-05-26 13:01:01 +00001924 if (offset == -1)
1925 break;
1926 next = start+offset;
1927 if (next == start) {
1928 /* replace with the 'to' */
1929 Py_MEMCPY(result_s, to_s, to_len);
1930 result_s += to_len;
1931 start += from_len;
1932 } else {
1933 /* copy the unchanged old then the 'to' */
1934 Py_MEMCPY(result_s, start, next-start);
1935 result_s += (next-start);
1936 Py_MEMCPY(result_s, to_s, to_len);
1937 result_s += to_len;
1938 start = next+from_len;
1939 }
1940 }
1941 /* Copy the remainder of the remaining bytes */
1942 Py_MEMCPY(result_s, start, end-start);
1943
1944 return result;
1945}
1946
1947
1948Py_LOCAL(PyByteArrayObject *)
1949replace(PyByteArrayObject *self,
1950 const char *from_s, Py_ssize_t from_len,
1951 const char *to_s, Py_ssize_t to_len,
1952 Py_ssize_t maxcount)
1953{
1954 if (maxcount < 0) {
1955 maxcount = PY_SSIZE_T_MAX;
1956 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1957 /* nothing to do; return the original bytes */
1958 return return_self(self);
1959 }
1960
1961 if (maxcount == 0 ||
1962 (from_len == 0 && to_len == 0)) {
1963 /* nothing to do; return the original bytes */
1964 return return_self(self);
1965 }
1966
1967 /* Handle zero-length special cases */
1968
1969 if (from_len == 0) {
1970 /* insert the 'to' bytes everywhere. */
1971 /* >>> "Python".replace("", ".") */
1972 /* '.P.y.t.h.o.n.' */
1973 return replace_interleave(self, to_s, to_len, maxcount);
1974 }
1975
1976 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1977 /* point for an empty self bytes to generate a non-empty bytes */
1978 /* Special case so the remaining code always gets a non-empty bytes */
1979 if (PyByteArray_GET_SIZE(self) == 0) {
1980 return return_self(self);
1981 }
1982
1983 if (to_len == 0) {
Martin Panter440bbd02016-09-08 05:22:16 +00001984 /* delete all occurrences of 'from' bytes */
Christian Heimes44720832008-05-26 13:01:01 +00001985 if (from_len == 1) {
1986 return replace_delete_single_character(
1987 self, from_s[0], maxcount);
1988 } else {
1989 return replace_delete_substring(self, from_s, from_len, maxcount);
1990 }
1991 }
1992
1993 /* Handle special case where both bytes have the same length */
1994
1995 if (from_len == to_len) {
1996 if (from_len == 1) {
1997 return replace_single_character_in_place(
1998 self,
1999 from_s[0],
2000 to_s[0],
2001 maxcount);
2002 } else {
2003 return replace_substring_in_place(
2004 self, from_s, from_len, to_s, to_len, maxcount);
2005 }
2006 }
2007
2008 /* Otherwise use the more generic algorithms */
2009 if (from_len == 1) {
2010 return replace_single_character(self, from_s[0],
2011 to_s, to_len, maxcount);
2012 } else {
2013 /* len('from')>=2, len('to')>=1 */
2014 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2015 }
2016}
2017
2018
2019PyDoc_STRVAR(replace__doc__,
2020"B.replace(old, new[, count]) -> bytes\n\
2021\n\
2022Return a copy of B with all occurrences of subsection\n\
2023old replaced by new. If the optional argument count is\n\
2024given, only the first count occurrences are replaced.");
2025
2026static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002027bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002028{
2029 Py_ssize_t count = -1;
2030 PyObject *from, *to, *res;
2031 Py_buffer vfrom, vto;
2032
2033 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2034 return NULL;
2035
2036 if (_getbuffer(from, &vfrom) < 0)
2037 return NULL;
2038 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002039 PyBuffer_Release(&vfrom);
Christian Heimes44720832008-05-26 13:01:01 +00002040 return NULL;
2041 }
2042
2043 res = (PyObject *)replace((PyByteArrayObject *) self,
2044 vfrom.buf, vfrom.len,
2045 vto.buf, vto.len, count);
2046
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002047 PyBuffer_Release(&vfrom);
2048 PyBuffer_Release(&vto);
Christian Heimes44720832008-05-26 13:01:01 +00002049 return res;
2050}
2051
Christian Heimes44720832008-05-26 13:01:01 +00002052PyDoc_STRVAR(split__doc__,
2053"B.split([sep[, maxsplit]]) -> list of bytearray\n\
2054\n\
2055Return a list of the sections in B, using sep as the delimiter.\n\
2056If sep is not given, B is split on ASCII whitespace characters\n\
2057(space, tab, return, newline, formfeed, vertical tab).\n\
2058If maxsplit is given, at most maxsplit splits are done.");
2059
2060static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002061bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002062{
Antoine Pitrou64672132010-01-13 07:55:48 +00002063 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2064 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002065 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002066 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002067 Py_buffer vsub;
Christian Heimes44720832008-05-26 13:01:01 +00002068
2069 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2070 return NULL;
2071 if (maxsplit < 0)
2072 maxsplit = PY_SSIZE_T_MAX;
2073
2074 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002075 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002076
2077 if (_getbuffer(subobj, &vsub) < 0)
2078 return NULL;
2079 sub = vsub.buf;
2080 n = vsub.len;
2081
Antoine Pitrou64672132010-01-13 07:55:48 +00002082 list = stringlib_split(
2083 (PyObject*) self, s, len, sub, n, maxsplit
2084 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002085 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002086 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002087}
2088
2089PyDoc_STRVAR(partition__doc__,
2090"B.partition(sep) -> (head, sep, tail)\n\
2091\n\
2092Searches for the separator sep in B, and returns the part before it,\n\
2093the separator itself, and the part after it. If the separator is not\n\
2094found, returns B and two empty bytearray objects.");
2095
2096static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002097bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002098{
2099 PyObject *bytesep, *result;
2100
2101 bytesep = PyByteArray_FromObject(sep_obj);
2102 if (! bytesep)
2103 return NULL;
2104
2105 result = stringlib_partition(
2106 (PyObject*) self,
2107 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2108 bytesep,
2109 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2110 );
2111
2112 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002113 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002114}
2115
2116PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti1fafaab2010-01-25 11:24:37 +00002117"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes44720832008-05-26 13:01:01 +00002118\n\
2119Searches for the separator sep in B, starting at the end of B,\n\
2120and returns the part before it, the separator itself, and the\n\
2121part after it. If the separator is not found, returns two empty\n\
2122bytearray objects and B.");
2123
2124static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002125bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002126{
2127 PyObject *bytesep, *result;
2128
2129 bytesep = PyByteArray_FromObject(sep_obj);
2130 if (! bytesep)
2131 return NULL;
2132
2133 result = stringlib_rpartition(
2134 (PyObject*) self,
2135 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2136 bytesep,
2137 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2138 );
2139
2140 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002141 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002142}
2143
2144PyDoc_STRVAR(rsplit__doc__,
2145"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2146\n\
2147Return a list of the sections in B, using sep as the delimiter,\n\
2148starting at the end of B and working to the front.\n\
2149If sep is not given, B is split on ASCII whitespace characters\n\
2150(space, tab, return, newline, formfeed, vertical tab).\n\
2151If maxsplit is given, at most maxsplit splits are done.");
2152
2153static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002154bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002155{
Antoine Pitrou64672132010-01-13 07:55:48 +00002156 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2157 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002158 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002159 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002160 Py_buffer vsub;
2161
2162 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2163 return NULL;
2164 if (maxsplit < 0)
2165 maxsplit = PY_SSIZE_T_MAX;
2166
2167 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002168 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002169
2170 if (_getbuffer(subobj, &vsub) < 0)
2171 return NULL;
2172 sub = vsub.buf;
2173 n = vsub.len;
2174
Antoine Pitrou64672132010-01-13 07:55:48 +00002175 list = stringlib_rsplit(
2176 (PyObject*) self, s, len, sub, n, maxsplit
2177 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002178 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002179 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002180}
2181
2182PyDoc_STRVAR(reverse__doc__,
2183"B.reverse() -> None\n\
2184\n\
2185Reverse the order of the values in B in place.");
2186static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002187bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes44720832008-05-26 13:01:01 +00002188{
2189 char swap, *head, *tail;
2190 Py_ssize_t i, j, n = Py_SIZE(self);
2191
2192 j = n / 2;
2193 head = self->ob_bytes;
2194 tail = head + n - 1;
2195 for (i = 0; i < j; i++) {
2196 swap = *head;
2197 *head++ = *tail;
2198 *tail-- = swap;
2199 }
2200
2201 Py_RETURN_NONE;
2202}
2203
2204PyDoc_STRVAR(insert__doc__,
2205"B.insert(index, int) -> None\n\
2206\n\
2207Insert a single item into the bytearray before the given index.");
2208static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002209bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002210{
Georg Brandl3e483f62008-07-16 22:57:41 +00002211 PyObject *value;
2212 int ival;
Christian Heimes44720832008-05-26 13:01:01 +00002213 Py_ssize_t where, n = Py_SIZE(self);
2214
Georg Brandl3e483f62008-07-16 22:57:41 +00002215 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes44720832008-05-26 13:01:01 +00002216 return NULL;
2217
2218 if (n == PY_SSIZE_T_MAX) {
2219 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002220 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002221 return NULL;
2222 }
Georg Brandl3e483f62008-07-16 22:57:41 +00002223 if (!_getbytevalue(value, &ival))
Christian Heimes44720832008-05-26 13:01:01 +00002224 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002225 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2226 return NULL;
2227
2228 if (where < 0) {
2229 where += n;
2230 if (where < 0)
2231 where = 0;
2232 }
2233 if (where > n)
2234 where = n;
2235 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl3e483f62008-07-16 22:57:41 +00002236 self->ob_bytes[where] = ival;
Christian Heimes44720832008-05-26 13:01:01 +00002237
2238 Py_RETURN_NONE;
2239}
2240
2241PyDoc_STRVAR(append__doc__,
2242"B.append(int) -> None\n\
2243\n\
2244Append a single item to the end of B.");
2245static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002246bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002247{
2248 int value;
2249 Py_ssize_t n = Py_SIZE(self);
2250
2251 if (! _getbytevalue(arg, &value))
2252 return NULL;
2253 if (n == PY_SSIZE_T_MAX) {
2254 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002255 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002256 return NULL;
2257 }
2258 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2259 return NULL;
2260
2261 self->ob_bytes[n] = value;
2262
2263 Py_RETURN_NONE;
2264}
2265
2266PyDoc_STRVAR(extend__doc__,
2267"B.extend(iterable int) -> None\n\
2268\n\
2269Append all the elements from the iterator or sequence to the\n\
2270end of B.");
2271static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002272bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002273{
Benjamin Petersond6720012009-04-18 15:31:34 +00002274 PyObject *it, *item, *bytearray_obj;
Christian Heimes44720832008-05-26 13:01:01 +00002275 Py_ssize_t buf_size = 0, len = 0;
2276 int value;
2277 char *buf;
2278
Benjamin Petersond6720012009-04-18 15:31:34 +00002279 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes44720832008-05-26 13:01:01 +00002280 if (PyObject_CheckBuffer(arg)) {
Benjamin Petersond6720012009-04-18 15:31:34 +00002281 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002282 return NULL;
2283
2284 Py_RETURN_NONE;
2285 }
2286
2287 it = PyObject_GetIter(arg);
2288 if (it == NULL)
2289 return NULL;
2290
Ezio Melotti24b07bc2011-03-15 18:55:01 +02002291 /* Try to determine the length of the argument. 32 is arbitrary. */
Christian Heimes44720832008-05-26 13:01:01 +00002292 buf_size = _PyObject_LengthHint(arg, 32);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002293 if (buf_size == -1) {
2294 Py_DECREF(it);
2295 return NULL;
2296 }
Christian Heimes44720832008-05-26 13:01:01 +00002297
Benjamin Petersond6720012009-04-18 15:31:34 +00002298 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitroufe941772012-04-01 16:05:46 +02002299 if (bytearray_obj == NULL) {
2300 Py_DECREF(it);
Christian Heimes44720832008-05-26 13:01:01 +00002301 return NULL;
Antoine Pitroufe941772012-04-01 16:05:46 +02002302 }
Benjamin Petersond6720012009-04-18 15:31:34 +00002303 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002304
2305 while ((item = PyIter_Next(it)) != NULL) {
2306 if (! _getbytevalue(item, &value)) {
2307 Py_DECREF(item);
2308 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002309 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002310 return NULL;
2311 }
2312 buf[len++] = value;
2313 Py_DECREF(item);
2314
2315 if (len >= buf_size) {
Martin Panter0c08fe02016-07-18 07:53:13 +00002316 Py_ssize_t addition;
2317 if (len == PY_SSIZE_T_MAX) {
2318 Py_DECREF(it);
2319 Py_DECREF(bytearray_obj);
2320 return PyErr_NoMemory();
2321 }
2322 addition = len >> 1;
2323 if (addition > PY_SSIZE_T_MAX - len - 1)
2324 buf_size = PY_SSIZE_T_MAX;
2325 else
2326 buf_size = len + addition + 1;
Benjamin Petersond6720012009-04-18 15:31:34 +00002327 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00002328 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002329 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002330 return NULL;
2331 }
2332 /* Recompute the `buf' pointer, since the resizing operation may
2333 have invalidated it. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002334 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002335 }
2336 }
2337 Py_DECREF(it);
2338
2339 /* Resize down to exact size. */
Benjamin Petersond6720012009-04-18 15:31:34 +00002340 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2341 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002342 return NULL;
2343 }
2344
Antoine Pitroufe941772012-04-01 16:05:46 +02002345 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2346 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002347 return NULL;
Antoine Pitroufe941772012-04-01 16:05:46 +02002348 }
Benjamin Petersond6720012009-04-18 15:31:34 +00002349 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002350
2351 Py_RETURN_NONE;
2352}
2353
2354PyDoc_STRVAR(pop__doc__,
2355"B.pop([index]) -> int\n\
2356\n\
2357Remove and return a single item from B. If no index\n\
Andrew M. Kuchlingd8972642008-06-21 13:29:12 +00002358argument is given, will pop the last value.");
Christian Heimes44720832008-05-26 13:01:01 +00002359static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002360bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002361{
2362 int value;
2363 Py_ssize_t where = -1, n = Py_SIZE(self);
2364
2365 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2366 return NULL;
2367
2368 if (n == 0) {
Eli Bendersky680e6eb2011-03-04 06:14:56 +00002369 PyErr_SetString(PyExc_IndexError,
2370 "pop from empty bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002371 return NULL;
2372 }
2373 if (where < 0)
2374 where += Py_SIZE(self);
2375 if (where < 0 || where >= Py_SIZE(self)) {
2376 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2377 return NULL;
2378 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002379 if (!_canresize(self))
2380 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002381
2382 value = self->ob_bytes[where];
2383 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2384 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2385 return NULL;
2386
Mark Dickinsonc8a7c7c2009-09-06 10:03:31 +00002387 return PyInt_FromLong((unsigned char)value);
Christian Heimes44720832008-05-26 13:01:01 +00002388}
2389
2390PyDoc_STRVAR(remove__doc__,
2391"B.remove(int) -> None\n\
2392\n\
Martin Panter440bbd02016-09-08 05:22:16 +00002393Remove the first occurrence of a value in B.");
Christian Heimes44720832008-05-26 13:01:01 +00002394static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002395bytearray_remove(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002396{
2397 int value;
Serhiy Storchakac742dff2016-05-16 22:15:57 +03002398 Py_ssize_t n = Py_SIZE(self);
2399 char *where;
Christian Heimes44720832008-05-26 13:01:01 +00002400
2401 if (! _getbytevalue(arg, &value))
2402 return NULL;
2403
Serhiy Storchakac742dff2016-05-16 22:15:57 +03002404 where = memchr(self->ob_bytes, value, n);
2405 if (!where) {
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002406 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002407 return NULL;
2408 }
Antoine Pitrouae5bece2008-12-06 21:29:24 +00002409 if (!_canresize(self))
2410 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002411
Serhiy Storchakac742dff2016-05-16 22:15:57 +03002412 memmove(where, where + 1, self->ob_bytes + n - where);
Christian Heimes44720832008-05-26 13:01:01 +00002413 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2414 return NULL;
2415
2416 Py_RETURN_NONE;
2417}
2418
2419/* XXX These two helpers could be optimized if argsize == 1 */
2420
2421static Py_ssize_t
2422lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2423 void *argptr, Py_ssize_t argsize)
2424{
2425 Py_ssize_t i = 0;
2426 while (i < mysize && memchr(argptr, myptr[i], argsize))
2427 i++;
2428 return i;
2429}
2430
2431static Py_ssize_t
2432rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2433 void *argptr, Py_ssize_t argsize)
2434{
2435 Py_ssize_t i = mysize - 1;
2436 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2437 i--;
2438 return i + 1;
2439}
2440
2441PyDoc_STRVAR(strip__doc__,
2442"B.strip([bytes]) -> bytearray\n\
2443\n\
2444Strip leading and trailing bytes contained in the argument.\n\
2445If the argument is omitted, strip ASCII whitespace.");
2446static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002447bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002448{
2449 Py_ssize_t left, right, mysize, argsize;
2450 void *myptr, *argptr;
2451 PyObject *arg = Py_None;
2452 Py_buffer varg;
2453 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2454 return NULL;
2455 if (arg == Py_None) {
2456 argptr = "\t\n\r\f\v ";
2457 argsize = 6;
2458 }
2459 else {
2460 if (_getbuffer(arg, &varg) < 0)
2461 return NULL;
2462 argptr = varg.buf;
2463 argsize = varg.len;
2464 }
2465 myptr = self->ob_bytes;
2466 mysize = Py_SIZE(self);
2467 left = lstrip_helper(myptr, mysize, argptr, argsize);
2468 if (left == mysize)
2469 right = left;
2470 else
2471 right = rstrip_helper(myptr, mysize, argptr, argsize);
2472 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002473 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002474 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2475}
2476
2477PyDoc_STRVAR(lstrip__doc__,
2478"B.lstrip([bytes]) -> bytearray\n\
2479\n\
2480Strip leading bytes contained in the argument.\n\
2481If the argument is omitted, strip leading ASCII whitespace.");
2482static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002483bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002484{
2485 Py_ssize_t left, right, mysize, argsize;
2486 void *myptr, *argptr;
2487 PyObject *arg = Py_None;
2488 Py_buffer varg;
2489 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2490 return NULL;
2491 if (arg == Py_None) {
2492 argptr = "\t\n\r\f\v ";
2493 argsize = 6;
2494 }
2495 else {
2496 if (_getbuffer(arg, &varg) < 0)
2497 return NULL;
2498 argptr = varg.buf;
2499 argsize = varg.len;
2500 }
2501 myptr = self->ob_bytes;
2502 mysize = Py_SIZE(self);
2503 left = lstrip_helper(myptr, mysize, argptr, argsize);
2504 right = mysize;
2505 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002506 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002507 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2508}
2509
2510PyDoc_STRVAR(rstrip__doc__,
2511"B.rstrip([bytes]) -> bytearray\n\
2512\n\
2513Strip trailing bytes contained in the argument.\n\
2514If the argument is omitted, strip trailing ASCII whitespace.");
2515static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002516bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002517{
2518 Py_ssize_t left, right, mysize, argsize;
2519 void *myptr, *argptr;
2520 PyObject *arg = Py_None;
2521 Py_buffer varg;
2522 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2523 return NULL;
2524 if (arg == Py_None) {
2525 argptr = "\t\n\r\f\v ";
2526 argsize = 6;
2527 }
2528 else {
2529 if (_getbuffer(arg, &varg) < 0)
2530 return NULL;
2531 argptr = varg.buf;
2532 argsize = varg.len;
2533 }
2534 myptr = self->ob_bytes;
2535 mysize = Py_SIZE(self);
2536 left = 0;
2537 right = rstrip_helper(myptr, mysize, argptr, argsize);
2538 if (arg != Py_None)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002539 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00002540 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2541}
2542
2543PyDoc_STRVAR(decode_doc,
2544"B.decode([encoding[, errors]]) -> unicode object.\n\
2545\n\
2546Decodes B using the codec registered for encoding. encoding defaults\n\
2547to the default encoding. errors may be given to set a different error\n\
2548handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2549a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2550as well as any other name registered with codecs.register_error that is\n\
2551able to handle UnicodeDecodeErrors.");
2552
2553static PyObject *
Benjamin Petersondc782b52009-09-18 21:46:21 +00002554bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes44720832008-05-26 13:01:01 +00002555{
2556 const char *encoding = NULL;
2557 const char *errors = NULL;
Benjamin Petersondc782b52009-09-18 21:46:21 +00002558 static char *kwlist[] = {"encoding", "errors", 0};
Christian Heimes44720832008-05-26 13:01:01 +00002559
Benjamin Petersondc782b52009-09-18 21:46:21 +00002560 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
Christian Heimes44720832008-05-26 13:01:01 +00002561 return NULL;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002562 if (encoding == NULL) {
2563#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002564 encoding = PyUnicode_GetDefaultEncoding();
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002565#else
2566 PyErr_SetString(PyExc_ValueError, "no encoding specified");
2567 return NULL;
2568#endif
2569 }
Serhiy Storchakac7797dc2015-05-31 20:21:00 +03002570 return _PyCodec_DecodeText(self, encoding, errors);
Christian Heimes44720832008-05-26 13:01:01 +00002571}
2572
2573PyDoc_STRVAR(alloc_doc,
2574"B.__alloc__() -> int\n\
2575\n\
2576Returns the number of bytes actually allocated.");
2577
2578static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002579bytearray_alloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002580{
2581 return PyInt_FromSsize_t(self->ob_alloc);
2582}
2583
2584PyDoc_STRVAR(join_doc,
2585"B.join(iterable_of_bytes) -> bytes\n\
2586\n\
2587Concatenates any number of bytearray objects, with B in between each pair.");
2588
2589static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002590bytearray_join(PyByteArrayObject *self, PyObject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002591{
2592 PyObject *seq;
2593 Py_ssize_t mysize = Py_SIZE(self);
2594 Py_ssize_t i;
2595 Py_ssize_t n;
2596 PyObject **items;
2597 Py_ssize_t totalsize = 0;
2598 PyObject *result;
2599 char *dest;
2600
2601 seq = PySequence_Fast(it, "can only join an iterable");
2602 if (seq == NULL)
2603 return NULL;
2604 n = PySequence_Fast_GET_SIZE(seq);
2605 items = PySequence_Fast_ITEMS(seq);
2606
2607 /* Compute the total size, and check that they are all bytes */
2608 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2609 for (i = 0; i < n; i++) {
2610 PyObject *obj = items[i];
2611 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2612 PyErr_Format(PyExc_TypeError,
2613 "can only join an iterable of bytes "
2614 "(item %ld has type '%.100s')",
2615 /* XXX %ld isn't right on Win64 */
2616 (long)i, Py_TYPE(obj)->tp_name);
2617 goto error;
2618 }
2619 if (i > 0)
2620 totalsize += mysize;
2621 totalsize += Py_SIZE(obj);
2622 if (totalsize < 0) {
2623 PyErr_NoMemory();
2624 goto error;
2625 }
2626 }
2627
2628 /* Allocate the result, and copy the bytes */
2629 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2630 if (result == NULL)
2631 goto error;
2632 dest = PyByteArray_AS_STRING(result);
2633 for (i = 0; i < n; i++) {
2634 PyObject *obj = items[i];
2635 Py_ssize_t size = Py_SIZE(obj);
2636 char *buf;
2637 if (PyByteArray_Check(obj))
2638 buf = PyByteArray_AS_STRING(obj);
2639 else
2640 buf = PyBytes_AS_STRING(obj);
2641 if (i) {
2642 memcpy(dest, self->ob_bytes, mysize);
2643 dest += mysize;
2644 }
2645 memcpy(dest, buf, size);
2646 dest += size;
2647 }
2648
2649 /* Done */
2650 Py_DECREF(seq);
2651 return result;
2652
2653 /* Error handling */
2654 error:
2655 Py_DECREF(seq);
2656 return NULL;
2657}
2658
Antoine Pitrou64672132010-01-13 07:55:48 +00002659PyDoc_STRVAR(splitlines__doc__,
Raymond Hettingeraad5b022012-06-02 01:42:58 -04002660"B.splitlines(keepends=False) -> list of lines\n\
Antoine Pitrou64672132010-01-13 07:55:48 +00002661\n\
2662Return a list of the lines in B, breaking at line boundaries.\n\
2663Line breaks are not included in the resulting list unless keepends\n\
2664is given and true.");
2665
2666static PyObject*
2667bytearray_splitlines(PyObject *self, PyObject *args)
2668{
2669 int keepends = 0;
2670
2671 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2672 return NULL;
2673
2674 return stringlib_splitlines(
2675 (PyObject*) self, PyByteArray_AS_STRING(self),
2676 PyByteArray_GET_SIZE(self), keepends
2677 );
2678}
2679
Christian Heimes44720832008-05-26 13:01:01 +00002680PyDoc_STRVAR(fromhex_doc,
2681"bytearray.fromhex(string) -> bytearray\n\
2682\n\
2683Create a bytearray object from a string of hexadecimal numbers.\n\
2684Spaces between two numbers are accepted.\n\
2685Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2686
2687static int
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002688hex_digit_to_int(char c)
Christian Heimes44720832008-05-26 13:01:01 +00002689{
Eric Smithcac7af62009-04-27 19:04:37 +00002690 if (Py_ISDIGIT(c))
Christian Heimes44720832008-05-26 13:01:01 +00002691 return c - '0';
2692 else {
Eric Smithcac7af62009-04-27 19:04:37 +00002693 if (Py_ISUPPER(c))
2694 c = Py_TOLOWER(c);
Christian Heimes44720832008-05-26 13:01:01 +00002695 if (c >= 'a' && c <= 'f')
2696 return c - 'a' + 10;
2697 }
2698 return -1;
2699}
2700
2701static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002702bytearray_fromhex(PyObject *cls, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002703{
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002704 PyObject *newbytes;
Christian Heimes44720832008-05-26 13:01:01 +00002705 char *buf;
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002706 char *hex;
Christian Heimes44720832008-05-26 13:01:01 +00002707 Py_ssize_t hexlen, byteslen, i, j;
2708 int top, bot;
2709
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002710 if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
Christian Heimes44720832008-05-26 13:01:01 +00002711 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002712 byteslen = hexlen/2; /* This overestimates if there are spaces */
2713 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2714 if (!newbytes)
2715 return NULL;
2716 buf = PyByteArray_AS_STRING(newbytes);
2717 for (i = j = 0; i < hexlen; i += 2) {
2718 /* skip over spaces in the input */
2719 while (hex[i] == ' ')
2720 i++;
2721 if (i >= hexlen)
2722 break;
2723 top = hex_digit_to_int(hex[i]);
2724 bot = hex_digit_to_int(hex[i+1]);
2725 if (top == -1 || bot == -1) {
2726 PyErr_Format(PyExc_ValueError,
2727 "non-hexadecimal number found in "
2728 "fromhex() arg at position %zd", i);
2729 goto error;
2730 }
2731 buf[j++] = (top << 4) + bot;
2732 }
2733 if (PyByteArray_Resize(newbytes, j) < 0)
2734 goto error;
2735 return newbytes;
2736
2737 error:
2738 Py_DECREF(newbytes);
2739 return NULL;
2740}
2741
2742PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2743
2744static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002745bytearray_reduce(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00002746{
2747 PyObject *latin1, *dict;
2748 if (self->ob_bytes)
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002749#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002750 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2751 Py_SIZE(self), NULL);
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002752#else
Mark Dickinson9d109742009-10-15 15:18:55 +00002753 latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002754#endif
Christian Heimes44720832008-05-26 13:01:01 +00002755 else
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002756#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +00002757 latin1 = PyUnicode_FromString("");
Benjamin Peterson78821dd2009-01-25 17:15:10 +00002758#else
2759 latin1 = PyString_FromString("");
2760#endif
Christian Heimes44720832008-05-26 13:01:01 +00002761
2762 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2763 if (dict == NULL) {
2764 PyErr_Clear();
2765 dict = Py_None;
2766 Py_INCREF(dict);
2767 }
2768
2769 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2770}
2771
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002772PyDoc_STRVAR(sizeof_doc,
2773"B.__sizeof__() -> int\n\
2774 \n\
2775Returns the size of B in memory, in bytes");
2776static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002777bytearray_sizeof(PyByteArrayObject *self)
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002778{
Georg Brandl517cfdc2009-04-05 13:16:35 +00002779 Py_ssize_t res;
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002780
Serhiy Storchakac06a6d02015-12-19 20:07:48 +02002781 res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002782 return PyInt_FromSsize_t(res);
Robert Schuppenies9be2ec12008-07-10 15:24:04 +00002783}
2784
Benjamin Petersond6720012009-04-18 15:31:34 +00002785static PySequenceMethods bytearray_as_sequence = {
2786 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes44720832008-05-26 13:01:01 +00002787 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Petersond6720012009-04-18 15:31:34 +00002788 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2789 (ssizeargfunc)bytearray_getitem, /* sq_item */
2790 0, /* sq_slice */
2791 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2792 0, /* sq_ass_slice */
2793 (objobjproc)bytearray_contains, /* sq_contains */
2794 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2795 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes44720832008-05-26 13:01:01 +00002796};
2797
Benjamin Petersond6720012009-04-18 15:31:34 +00002798static PyMappingMethods bytearray_as_mapping = {
2799 (lenfunc)bytearray_length,
2800 (binaryfunc)bytearray_subscript,
2801 (objobjargproc)bytearray_ass_subscript,
Christian Heimes44720832008-05-26 13:01:01 +00002802};
2803
Benjamin Petersond6720012009-04-18 15:31:34 +00002804static PyBufferProcs bytearray_as_buffer = {
2805 (readbufferproc)bytearray_buffer_getreadbuf,
2806 (writebufferproc)bytearray_buffer_getwritebuf,
2807 (segcountproc)bytearray_buffer_getsegcount,
2808 (charbufferproc)bytearray_buffer_getcharbuf,
2809 (getbufferproc)bytearray_getbuffer,
2810 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes44720832008-05-26 13:01:01 +00002811};
2812
2813static PyMethodDef
Benjamin Petersond6720012009-04-18 15:31:34 +00002814bytearray_methods[] = {
2815 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2816 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2817 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2818 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002819 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2820 _Py_capitalize__doc__},
2821 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002822 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Benjamin Petersondc782b52009-09-18 21:46:21 +00002823 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002824 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002825 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2826 expandtabs__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002827 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2828 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2829 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
Christian Heimes44720832008-05-26 13:01:01 +00002830 fromhex_doc},
Benjamin Petersond6720012009-04-18 15:31:34 +00002831 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2832 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002833 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2834 _Py_isalnum__doc__},
2835 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2836 _Py_isalpha__doc__},
2837 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2838 _Py_isdigit__doc__},
2839 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2840 _Py_islower__doc__},
2841 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2842 _Py_isspace__doc__},
2843 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2844 _Py_istitle__doc__},
2845 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2846 _Py_isupper__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002847 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
Christian Heimes44720832008-05-26 13:01:01 +00002848 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2849 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002850 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2851 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2852 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2853 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2854 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2855 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2856 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2857 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002858 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002859 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2860 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2861 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2862 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
Antoine Pitrou64672132010-01-13 07:55:48 +00002863 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002864 splitlines__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002865 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes44720832008-05-26 13:01:01 +00002866 startswith__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002867 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
Christian Heimes44720832008-05-26 13:01:01 +00002868 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2869 _Py_swapcase__doc__},
2870 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Benjamin Petersond6720012009-04-18 15:31:34 +00002871 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
Christian Heimes44720832008-05-26 13:01:01 +00002872 translate__doc__},
2873 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2874 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2875 {NULL}
2876};
2877
Benjamin Petersond6720012009-04-18 15:31:34 +00002878PyDoc_STRVAR(bytearray_doc,
Christian Heimes44720832008-05-26 13:01:01 +00002879"bytearray(iterable_of_ints) -> bytearray.\n\
2880bytearray(string, encoding[, errors]) -> bytearray.\n\
2881bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
2882bytearray(memory_view) -> bytearray.\n\
2883\n\
Serhiy Storchaka9a118f12016-04-17 09:37:36 +03002884Construct a mutable bytearray object from:\n\
Christian Heimes44720832008-05-26 13:01:01 +00002885 - an iterable yielding integers in range(256)\n\
2886 - a text string encoded using the specified encoding\n\
2887 - a bytes or a bytearray object\n\
2888 - any object implementing the buffer API.\n\
2889\n\
2890bytearray(int) -> bytearray.\n\
2891\n\
2892Construct a zero-initialized bytearray of the given length.");
2893
2894
Benjamin Petersond6720012009-04-18 15:31:34 +00002895static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes44720832008-05-26 13:01:01 +00002896
2897PyTypeObject PyByteArray_Type = {
2898 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2899 "bytearray",
2900 sizeof(PyByteArrayObject),
2901 0,
Benjamin Petersond6720012009-04-18 15:31:34 +00002902 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00002903 0, /* tp_print */
2904 0, /* tp_getattr */
2905 0, /* tp_setattr */
2906 0, /* tp_compare */
Benjamin Petersond6720012009-04-18 15:31:34 +00002907 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes44720832008-05-26 13:01:01 +00002908 0, /* tp_as_number */
Benjamin Petersond6720012009-04-18 15:31:34 +00002909 &bytearray_as_sequence, /* tp_as_sequence */
2910 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes44720832008-05-26 13:01:01 +00002911 0, /* tp_hash */
2912 0, /* tp_call */
Benjamin Petersond6720012009-04-18 15:31:34 +00002913 bytearray_str, /* tp_str */
Christian Heimes44720832008-05-26 13:01:01 +00002914 PyObject_GenericGetAttr, /* tp_getattro */
2915 0, /* tp_setattro */
Benjamin Petersond6720012009-04-18 15:31:34 +00002916 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes44720832008-05-26 13:01:01 +00002917 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2918 Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
Benjamin Petersond6720012009-04-18 15:31:34 +00002919 bytearray_doc, /* tp_doc */
Christian Heimes44720832008-05-26 13:01:01 +00002920 0, /* tp_traverse */
2921 0, /* tp_clear */
Benjamin Petersond6720012009-04-18 15:31:34 +00002922 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes44720832008-05-26 13:01:01 +00002923 0, /* tp_weaklistoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002924 bytearray_iter, /* tp_iter */
Christian Heimes44720832008-05-26 13:01:01 +00002925 0, /* tp_iternext */
Benjamin Petersond6720012009-04-18 15:31:34 +00002926 bytearray_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00002927 0, /* tp_members */
2928 0, /* tp_getset */
2929 0, /* tp_base */
2930 0, /* tp_dict */
2931 0, /* tp_descr_get */
2932 0, /* tp_descr_set */
2933 0, /* tp_dictoffset */
Benjamin Petersond6720012009-04-18 15:31:34 +00002934 (initproc)bytearray_init, /* tp_init */
Christian Heimes44720832008-05-26 13:01:01 +00002935 PyType_GenericAlloc, /* tp_alloc */
2936 PyType_GenericNew, /* tp_new */
2937 PyObject_Del, /* tp_free */
2938};
2939
2940/*********************** Bytes Iterator ****************************/
2941
2942typedef struct {
2943 PyObject_HEAD
2944 Py_ssize_t it_index;
2945 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2946} bytesiterobject;
2947
2948static void
Benjamin Petersond6720012009-04-18 15:31:34 +00002949bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002950{
2951 _PyObject_GC_UNTRACK(it);
2952 Py_XDECREF(it->it_seq);
2953 PyObject_GC_Del(it);
2954}
2955
2956static int
Benjamin Petersond6720012009-04-18 15:31:34 +00002957bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002958{
2959 Py_VISIT(it->it_seq);
2960 return 0;
2961}
2962
2963static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002964bytearrayiter_next(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002965{
2966 PyByteArrayObject *seq;
2967 PyObject *item;
2968
2969 assert(it != NULL);
2970 seq = it->it_seq;
2971 if (seq == NULL)
2972 return NULL;
2973 assert(PyByteArray_Check(seq));
2974
2975 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2976 item = PyInt_FromLong(
2977 (unsigned char)seq->ob_bytes[it->it_index]);
2978 if (item != NULL)
2979 ++it->it_index;
2980 return item;
2981 }
2982
Christian Heimes44720832008-05-26 13:01:01 +00002983 it->it_seq = NULL;
Serhiy Storchaka14a7d632016-03-30 20:43:06 +03002984 Py_DECREF(seq);
Christian Heimes44720832008-05-26 13:01:01 +00002985 return NULL;
2986}
2987
2988static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002989bytesarrayiter_length_hint(bytesiterobject *it)
Christian Heimes44720832008-05-26 13:01:01 +00002990{
2991 Py_ssize_t len = 0;
2992 if (it->it_seq)
2993 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2994 return PyInt_FromSsize_t(len);
2995}
2996
2997PyDoc_STRVAR(length_hint_doc,
2998 "Private method returning an estimate of len(list(it)).");
2999
Benjamin Petersond6720012009-04-18 15:31:34 +00003000static PyMethodDef bytearrayiter_methods[] = {
3001 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
Christian Heimes44720832008-05-26 13:01:01 +00003002 length_hint_doc},
3003 {NULL, NULL} /* sentinel */
3004};
3005
3006PyTypeObject PyByteArrayIter_Type = {
3007 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3008 "bytearray_iterator", /* tp_name */
3009 sizeof(bytesiterobject), /* tp_basicsize */
3010 0, /* tp_itemsize */
3011 /* methods */
Benjamin Petersond6720012009-04-18 15:31:34 +00003012 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes44720832008-05-26 13:01:01 +00003013 0, /* tp_print */
3014 0, /* tp_getattr */
3015 0, /* tp_setattr */
3016 0, /* tp_compare */
3017 0, /* tp_repr */
3018 0, /* tp_as_number */
3019 0, /* tp_as_sequence */
3020 0, /* tp_as_mapping */
3021 0, /* tp_hash */
3022 0, /* tp_call */
3023 0, /* tp_str */
3024 PyObject_GenericGetAttr, /* tp_getattro */
3025 0, /* tp_setattro */
3026 0, /* tp_as_buffer */
3027 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3028 0, /* tp_doc */
Benjamin Petersond6720012009-04-18 15:31:34 +00003029 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes44720832008-05-26 13:01:01 +00003030 0, /* tp_clear */
3031 0, /* tp_richcompare */
3032 0, /* tp_weaklistoffset */
3033 PyObject_SelfIter, /* tp_iter */
Benjamin Petersond6720012009-04-18 15:31:34 +00003034 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3035 bytearrayiter_methods, /* tp_methods */
Christian Heimes44720832008-05-26 13:01:01 +00003036 0,
3037};
3038
3039static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00003040bytearray_iter(PyObject *seq)
Christian Heimes44720832008-05-26 13:01:01 +00003041{
3042 bytesiterobject *it;
3043
3044 if (!PyByteArray_Check(seq)) {
3045 PyErr_BadInternalCall();
3046 return NULL;
3047 }
3048 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3049 if (it == NULL)
3050 return NULL;
3051 it->it_index = 0;
3052 Py_INCREF(seq);
3053 it->it_seq = (PyByteArrayObject *)seq;
3054 _PyObject_GC_TRACK(it);
3055 return (PyObject *)it;
3056}