blob: a90bdebb162c1c3dfa317397f6b168ad68ae66e4 [file] [log] [blame]
Christian Heimes44720832008-05-26 13:01:01 +00001/* PyBytes (bytearray) implementation */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
5#include "structmember.h"
6#include "bytes_methods.h"
7
Antoine Pitroue80a6a42010-01-17 12:26:20 +00008char _PyByteArray_empty_string[] = "";
Christian Heimes44720832008-05-26 13:01:01 +00009
10void
11PyByteArray_Fini(void)
12{
Christian Heimes44720832008-05-26 13:01:01 +000013}
14
15int
16PyByteArray_Init(void)
17{
Christian Heimes44720832008-05-26 13:01:01 +000018 return 1;
19}
20
21/* end nullbytes support */
22
23/* Helpers */
24
25static int
26_getbytevalue(PyObject* arg, int *value)
27{
28 long face_value;
29
Georg Brandl3e483f62008-07-16 22:57:41 +000030 if (PyBytes_CheckExact(arg)) {
Christian Heimes44720832008-05-26 13:01:01 +000031 if (Py_SIZE(arg) != 1) {
32 PyErr_SetString(PyExc_ValueError, "string must be of size 1");
33 return 0;
34 }
Georg Brandl3e483f62008-07-16 22:57:41 +000035 *value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
36 return 1;
37 }
38 else if (PyInt_Check(arg) || PyLong_Check(arg)) {
39 face_value = PyLong_AsLong(arg);
Christian Heimes44720832008-05-26 13:01:01 +000040 }
41 else {
Georg Brandl3e483f62008-07-16 22:57:41 +000042 PyObject *index = PyNumber_Index(arg);
43 if (index == NULL) {
44 PyErr_Format(PyExc_TypeError,
45 "an integer or string of size 1 is required");
46 return 0;
47 }
48 face_value = PyLong_AsLong(index);
49 Py_DECREF(index);
50 }
Georg Brandl3e483f62008-07-16 22:57:41 +000051
52 if (face_value < 0 || face_value >= 256) {
Georg Brandl3238a3e2008-07-16 23:17:46 +000053 /* this includes the OverflowError in case the long is too large */
Georg Brandl3e483f62008-07-16 22:57:41 +000054 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Christian Heimes44720832008-05-26 13:01:01 +000055 return 0;
56 }
57
58 *value = face_value;
59 return 1;
60}
61
62static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000063bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000064{
65 if ( index != 0 ) {
66 PyErr_SetString(PyExc_SystemError,
67 "accessing non-existent bytes segment");
68 return -1;
69 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +000070 *ptr = (void *)PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +000071 return Py_SIZE(self);
72}
73
74static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000075bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000076{
77 if ( index != 0 ) {
78 PyErr_SetString(PyExc_SystemError,
79 "accessing non-existent bytes segment");
80 return -1;
81 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +000082 *ptr = (void *)PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +000083 return Py_SIZE(self);
84}
85
86static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000087bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
Christian Heimes44720832008-05-26 13:01:01 +000088{
89 if ( lenp )
90 *lenp = Py_SIZE(self);
91 return 1;
92}
93
94static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +000095bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
Christian Heimes44720832008-05-26 13:01:01 +000096{
97 if ( index != 0 ) {
98 PyErr_SetString(PyExc_SystemError,
99 "accessing non-existent bytes segment");
100 return -1;
101 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000102 *ptr = PyByteArray_AS_STRING(self);
Christian Heimes44720832008-05-26 13:01:01 +0000103 return Py_SIZE(self);
104}
105
106static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000107bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes44720832008-05-26 13:01:01 +0000108{
Antoine Pitrou619f16e2010-06-09 16:24:00 +0000109 int ret;
110 void *ptr;
111 if (view == NULL) {
112 obj->ob_exports++;
113 return 0;
114 }
115 ptr = (void *) PyByteArray_AS_STRING(obj);
116 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
117 if (ret >= 0) {
118 obj->ob_exports++;
119 }
120 return ret;
Christian Heimes44720832008-05-26 13:01:01 +0000121}
122
123static void
Benjamin Petersond6720012009-04-18 15:31:34 +0000124bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes44720832008-05-26 13:01:01 +0000125{
Antoine Pitrou619f16e2010-06-09 16:24:00 +0000126 obj->ob_exports--;
Christian Heimes44720832008-05-26 13:01:01 +0000127}
128
129static Py_ssize_t
130_getbuffer(PyObject *obj, Py_buffer *view)
131{
132 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
133
134 if (buffer == NULL || buffer->bf_getbuffer == NULL)
135 {
136 PyErr_Format(PyExc_TypeError,
137 "Type %.100s doesn't support the buffer API",
138 Py_TYPE(obj)->tp_name);
139 return -1;
140 }
141
142 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
143 return -1;
144 return view->len;
145}
146
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000147static int
148_canresize(PyByteArrayObject *self)
149{
150 if (self->ob_exports > 0) {
151 PyErr_SetString(PyExc_BufferError,
152 "Existing exports of data: object cannot be re-sized");
153 return 0;
154 }
155 return 1;
156}
157
Christian Heimes44720832008-05-26 13:01:01 +0000158/* Direct API functions */
159
160PyObject *
161PyByteArray_FromObject(PyObject *input)
162{
163 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
164 input, NULL);
165}
166
167PyObject *
168PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
169{
170 PyByteArrayObject *new;
171 Py_ssize_t alloc;
172
173 if (size < 0) {
174 PyErr_SetString(PyExc_SystemError,
175 "Negative size passed to PyByteArray_FromStringAndSize");
176 return NULL;
177 }
178
179 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
180 if (new == NULL)
181 return NULL;
182
183 if (size == 0) {
184 new->ob_bytes = NULL;
185 alloc = 0;
186 }
187 else {
188 alloc = size + 1;
189 new->ob_bytes = PyMem_Malloc(alloc);
190 if (new->ob_bytes == NULL) {
191 Py_DECREF(new);
192 return PyErr_NoMemory();
193 }
Antoine Pitroue80a6a42010-01-17 12:26:20 +0000194 if (bytes != NULL && size > 0)
Christian Heimes44720832008-05-26 13:01:01 +0000195 memcpy(new->ob_bytes, bytes, size);
196 new->ob_bytes[size] = '\0'; /* Trailing null byte */
197 }
198 Py_SIZE(new) = size;
199 new->ob_alloc = alloc;
200 new->ob_exports = 0;
201
202 return (PyObject *)new;
203}
204
205Py_ssize_t
206PyByteArray_Size(PyObject *self)
207{
208 assert(self != NULL);
209 assert(PyByteArray_Check(self));
210
211 return PyByteArray_GET_SIZE(self);
212}
213
214char *
215PyByteArray_AsString(PyObject *self)
216{
217 assert(self != NULL);
218 assert(PyByteArray_Check(self));
219
220 return PyByteArray_AS_STRING(self);
221}
222
223int
224PyByteArray_Resize(PyObject *self, Py_ssize_t size)
225{
226 void *sval;
227 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
228
229 assert(self != NULL);
230 assert(PyByteArray_Check(self));
231 assert(size >= 0);
232
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000233 if (size == Py_SIZE(self)) {
234 return 0;
235 }
236 if (!_canresize((PyByteArrayObject *)self)) {
237 return -1;
238 }
239
Christian Heimes44720832008-05-26 13:01:01 +0000240 if (size < alloc / 2) {
241 /* Major downsize; resize down to exact size */
242 alloc = size + 1;
243 }
244 else if (size < alloc) {
245 /* Within allocated size; quick exit */
246 Py_SIZE(self) = size;
247 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
248 return 0;
249 }
250 else if (size <= alloc * 1.125) {
251 /* Moderate upsize; overallocate similar to list_resize() */
252 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
253 }
254 else {
255 /* Major upsize; resize up to exact size */
256 alloc = size + 1;
257 }
258
Christian Heimes44720832008-05-26 13:01:01 +0000259 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
260 if (sval == NULL) {
261 PyErr_NoMemory();
262 return -1;
263 }
264
265 ((PyByteArrayObject *)self)->ob_bytes = sval;
266 Py_SIZE(self) = size;
267 ((PyByteArrayObject *)self)->ob_alloc = alloc;
268 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
269
270 return 0;
271}
272
273PyObject *
274PyByteArray_Concat(PyObject *a, PyObject *b)
275{
276 Py_ssize_t size;
277 Py_buffer va, vb;
278 PyByteArrayObject *result = NULL;
279
280 va.len = -1;
281 vb.len = -1;
282 if (_getbuffer(a, &va) < 0 ||
283 _getbuffer(b, &vb) < 0) {
284 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
285 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
286 goto done;
287 }
288
289 size = va.len + vb.len;
290 if (size < 0) {
Hirokazu Yamamotoa3e6c972009-03-05 09:34:14 +0000291 PyErr_NoMemory();
Christian Heimes44720832008-05-26 13:01:01 +0000292 goto done;
293 }
294
295 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
296 if (result != NULL) {
297 memcpy(result->ob_bytes, va.buf, va.len);
298 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
299 }
300
301 done:
302 if (va.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000303 PyBuffer_Release(&va);
Christian Heimes44720832008-05-26 13:01:01 +0000304 if (vb.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000305 PyBuffer_Release(&vb);
Christian Heimes44720832008-05-26 13:01:01 +0000306 return (PyObject *)result;
307}
308
309/* Functions stuffed into the type object */
310
311static Py_ssize_t
Benjamin Petersond6720012009-04-18 15:31:34 +0000312bytearray_length(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000313{
314 return Py_SIZE(self);
315}
316
317static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000318bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes44720832008-05-26 13:01:01 +0000319{
320 Py_ssize_t mysize;
321 Py_ssize_t size;
322 Py_buffer vo;
323
324 if (_getbuffer(other, &vo) < 0) {
325 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
326 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
327 return NULL;
328 }
329
330 mysize = Py_SIZE(self);
331 size = mysize + vo.len;
332 if (size < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000333 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000334 return PyErr_NoMemory();
335 }
336 if (size < self->ob_alloc) {
337 Py_SIZE(self) = size;
338 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
339 }
340 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000341 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000342 return NULL;
343 }
344 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000345 PyBuffer_Release(&vo);
Christian Heimes44720832008-05-26 13:01:01 +0000346 Py_INCREF(self);
347 return (PyObject *)self;
348}
349
350static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000351bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000352{
353 PyByteArrayObject *result;
354 Py_ssize_t mysize;
355 Py_ssize_t size;
356
357 if (count < 0)
358 count = 0;
359 mysize = Py_SIZE(self);
360 size = mysize * count;
361 if (count != 0 && size / count != mysize)
362 return PyErr_NoMemory();
363 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
364 if (result != NULL && size != 0) {
365 if (mysize == 1)
366 memset(result->ob_bytes, self->ob_bytes[0], size);
367 else {
368 Py_ssize_t i;
369 for (i = 0; i < count; i++)
370 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
371 }
372 }
373 return (PyObject *)result;
374}
375
376static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000377bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes44720832008-05-26 13:01:01 +0000378{
379 Py_ssize_t mysize;
380 Py_ssize_t size;
381
382 if (count < 0)
383 count = 0;
384 mysize = Py_SIZE(self);
385 size = mysize * count;
386 if (count != 0 && size / count != mysize)
387 return PyErr_NoMemory();
388 if (size < self->ob_alloc) {
389 Py_SIZE(self) = size;
390 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
391 }
392 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
393 return NULL;
394
395 if (mysize == 1)
396 memset(self->ob_bytes, self->ob_bytes[0], size);
397 else {
398 Py_ssize_t i;
399 for (i = 1; i < count; i++)
400 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
401 }
402
403 Py_INCREF(self);
404 return (PyObject *)self;
405}
406
407static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000408bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes44720832008-05-26 13:01:01 +0000409{
410 if (i < 0)
411 i += Py_SIZE(self);
412 if (i < 0 || i >= Py_SIZE(self)) {
413 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
414 return NULL;
415 }
416 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
417}
418
419static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000420bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes44720832008-05-26 13:01:01 +0000421{
Georg Brandl3e483f62008-07-16 22:57:41 +0000422 if (PyIndex_Check(index)) {
423 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000424
425 if (i == -1 && PyErr_Occurred())
426 return NULL;
427
428 if (i < 0)
429 i += PyByteArray_GET_SIZE(self);
430
431 if (i < 0 || i >= Py_SIZE(self)) {
432 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
433 return NULL;
434 }
435 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
436 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000437 else if (PySlice_Check(index)) {
Christian Heimes44720832008-05-26 13:01:01 +0000438 Py_ssize_t start, stop, step, slicelength, cur, i;
Georg Brandl3e483f62008-07-16 22:57:41 +0000439 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes44720832008-05-26 13:01:01 +0000440 PyByteArray_GET_SIZE(self),
441 &start, &stop, &step, &slicelength) < 0) {
442 return NULL;
443 }
444
445 if (slicelength <= 0)
446 return PyByteArray_FromStringAndSize("", 0);
447 else if (step == 1) {
448 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
449 slicelength);
450 }
451 else {
452 char *source_buf = PyByteArray_AS_STRING(self);
453 char *result_buf = (char *)PyMem_Malloc(slicelength);
454 PyObject *result;
455
456 if (result_buf == NULL)
457 return PyErr_NoMemory();
458
459 for (cur = start, i = 0; i < slicelength;
460 cur += step, i++) {
461 result_buf[i] = source_buf[cur];
462 }
463 result = PyByteArray_FromStringAndSize(result_buf, slicelength);
464 PyMem_Free(result_buf);
465 return result;
466 }
467 }
468 else {
469 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
470 return NULL;
471 }
472}
473
474static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000475bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes44720832008-05-26 13:01:01 +0000476 PyObject *values)
477{
478 Py_ssize_t avail, needed;
479 void *bytes;
480 Py_buffer vbytes;
481 int res = 0;
482
483 vbytes.len = -1;
484 if (values == (PyObject *)self) {
485 /* Make a copy and call this function recursively */
486 int err;
487 values = PyByteArray_FromObject(values);
488 if (values == NULL)
489 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000490 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes44720832008-05-26 13:01:01 +0000491 Py_DECREF(values);
492 return err;
493 }
494 if (values == NULL) {
495 /* del b[lo:hi] */
496 bytes = NULL;
497 needed = 0;
498 }
499 else {
500 if (_getbuffer(values, &vbytes) < 0) {
501 PyErr_Format(PyExc_TypeError,
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000502 "can't set bytearray slice from %.100s",
Christian Heimes44720832008-05-26 13:01:01 +0000503 Py_TYPE(values)->tp_name);
504 return -1;
505 }
506 needed = vbytes.len;
507 bytes = vbytes.buf;
508 }
509
510 if (lo < 0)
511 lo = 0;
512 if (hi < lo)
513 hi = lo;
514 if (hi > Py_SIZE(self))
515 hi = Py_SIZE(self);
516
517 avail = hi - lo;
518 if (avail < 0)
519 lo = hi = avail = 0;
520
521 if (avail != needed) {
522 if (avail > needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000523 if (!_canresize(self)) {
524 res = -1;
525 goto finish;
526 }
Christian Heimes44720832008-05-26 13:01:01 +0000527 /*
528 0 lo hi old_size
529 | |<----avail----->|<-----tomove------>|
530 | |<-needed->|<-----tomove------>|
531 0 lo new_hi new_size
532 */
533 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
534 Py_SIZE(self) - hi);
535 }
536 /* XXX(nnorwitz): need to verify this can't overflow! */
537 if (PyByteArray_Resize((PyObject *)self,
538 Py_SIZE(self) + needed - avail) < 0) {
539 res = -1;
540 goto finish;
541 }
542 if (avail < needed) {
543 /*
544 0 lo hi old_size
545 | |<-avail->|<-----tomove------>|
546 | |<----needed---->|<-----tomove------>|
547 0 lo new_hi new_size
548 */
549 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
550 Py_SIZE(self) - lo - needed);
551 }
552 }
553
554 if (needed > 0)
555 memcpy(self->ob_bytes + lo, bytes, needed);
556
557
558 finish:
559 if (vbytes.len != -1)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000560 PyBuffer_Release(&vbytes);
Christian Heimes44720832008-05-26 13:01:01 +0000561 return res;
562}
563
564static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000565bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes44720832008-05-26 13:01:01 +0000566{
567 int ival;
568
569 if (i < 0)
570 i += Py_SIZE(self);
571
572 if (i < 0 || i >= Py_SIZE(self)) {
573 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
574 return -1;
575 }
576
577 if (value == NULL)
Benjamin Petersond6720012009-04-18 15:31:34 +0000578 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes44720832008-05-26 13:01:01 +0000579
580 if (!_getbytevalue(value, &ival))
581 return -1;
582
583 self->ob_bytes[i] = ival;
584 return 0;
585}
586
587static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000588bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes44720832008-05-26 13:01:01 +0000589{
590 Py_ssize_t start, stop, step, slicelen, needed;
591 char *bytes;
592
Georg Brandl3e483f62008-07-16 22:57:41 +0000593 if (PyIndex_Check(index)) {
594 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes44720832008-05-26 13:01:01 +0000595
596 if (i == -1 && PyErr_Occurred())
597 return -1;
598
599 if (i < 0)
600 i += PyByteArray_GET_SIZE(self);
601
602 if (i < 0 || i >= Py_SIZE(self)) {
603 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
604 return -1;
605 }
606
607 if (values == NULL) {
608 /* Fall through to slice assignment */
609 start = i;
610 stop = i + 1;
611 step = 1;
612 slicelen = 1;
613 }
614 else {
Georg Brandl3e483f62008-07-16 22:57:41 +0000615 int ival;
616 if (!_getbytevalue(values, &ival))
Christian Heimes44720832008-05-26 13:01:01 +0000617 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000618 self->ob_bytes[i] = (char)ival;
619 return 0;
620 }
621 }
Georg Brandl3e483f62008-07-16 22:57:41 +0000622 else if (PySlice_Check(index)) {
623 if (PySlice_GetIndicesEx((PySliceObject *)index,
Christian Heimes44720832008-05-26 13:01:01 +0000624 PyByteArray_GET_SIZE(self),
625 &start, &stop, &step, &slicelen) < 0) {
626 return -1;
627 }
628 }
629 else {
630 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
631 return -1;
632 }
633
634 if (values == NULL) {
635 bytes = NULL;
636 needed = 0;
637 }
638 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes146a5fe2012-11-03 23:07:59 +0100639 int err;
Ezio Melotti67dc4a82012-11-03 21:10:45 +0200640 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
641 PyErr_SetString(PyExc_TypeError,
642 "can assign only bytes, buffers, or iterables "
643 "of ints in range(0, 256)");
644 return -1;
645 }
Georg Brandl28dadd92011-02-25 10:50:32 +0000646 /* Make a copy and call this function recursively */
Christian Heimes44720832008-05-26 13:01:01 +0000647 values = PyByteArray_FromObject(values);
648 if (values == NULL)
649 return -1;
Benjamin Petersond6720012009-04-18 15:31:34 +0000650 err = bytearray_ass_subscript(self, index, values);
Christian Heimes44720832008-05-26 13:01:01 +0000651 Py_DECREF(values);
652 return err;
653 }
654 else {
655 assert(PyByteArray_Check(values));
656 bytes = ((PyByteArrayObject *)values)->ob_bytes;
657 needed = Py_SIZE(values);
658 }
659 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
660 if ((step < 0 && start < stop) ||
661 (step > 0 && start > stop))
662 stop = start;
663 if (step == 1) {
664 if (slicelen != needed) {
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000665 if (!_canresize(self))
666 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000667 if (slicelen > needed) {
668 /*
669 0 start stop old_size
670 | |<---slicelen--->|<-----tomove------>|
671 | |<-needed->|<-----tomove------>|
672 0 lo new_hi new_size
673 */
674 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
675 Py_SIZE(self) - stop);
676 }
677 if (PyByteArray_Resize((PyObject *)self,
678 Py_SIZE(self) + needed - slicelen) < 0)
679 return -1;
680 if (slicelen < needed) {
681 /*
682 0 lo hi old_size
683 | |<-avail->|<-----tomove------>|
684 | |<----needed---->|<-----tomove------>|
685 0 lo new_hi new_size
686 */
687 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
688 Py_SIZE(self) - start - needed);
689 }
690 }
691
692 if (needed > 0)
693 memcpy(self->ob_bytes + start, bytes, needed);
694
695 return 0;
696 }
697 else {
698 if (needed == 0) {
699 /* Delete slice */
Mark Dickinson36ecd672010-01-29 17:11:39 +0000700 size_t cur;
701 Py_ssize_t i;
Christian Heimes44720832008-05-26 13:01:01 +0000702
Antoine Pitrouae5bece2008-12-06 21:29:24 +0000703 if (!_canresize(self))
704 return -1;
Christian Heimes44720832008-05-26 13:01:01 +0000705 if (step < 0) {
706 stop = start + 1;
707 start = stop + step * (slicelen - 1) - 1;
708 step = -step;
709 }
710 for (cur = start, i = 0;
711 i < slicelen; cur += step, i++) {
712 Py_ssize_t lim = step - 1;
713
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000714 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes44720832008-05-26 13:01:01 +0000715 lim = PyByteArray_GET_SIZE(self) - cur - 1;
716
717 memmove(self->ob_bytes + cur - i,
718 self->ob_bytes + cur + 1, lim);
719 }
720 /* Move the tail of the bytes, in one chunk */
721 cur = start + slicelen*step;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000722 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Christian Heimes44720832008-05-26 13:01:01 +0000723 memmove(self->ob_bytes + cur - slicelen,
724 self->ob_bytes + cur,
725 PyByteArray_GET_SIZE(self) - cur);
726 }
727 if (PyByteArray_Resize((PyObject *)self,
728 PyByteArray_GET_SIZE(self) - slicelen) < 0)
729 return -1;
730
731 return 0;
732 }
733 else {
734 /* Assign slice */
735 Py_ssize_t cur, i;
736
737 if (needed != slicelen) {
738 PyErr_Format(PyExc_ValueError,
739 "attempt to assign bytes of size %zd "
740 "to extended slice of size %zd",
741 needed, slicelen);
742 return -1;
743 }
744 for (cur = start, i = 0; i < slicelen; cur += step, i++)
745 self->ob_bytes[cur] = bytes[i];
746 return 0;
747 }
748 }
749}
750
751static int
Benjamin Petersond6720012009-04-18 15:31:34 +0000752bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes44720832008-05-26 13:01:01 +0000753{
754 static char *kwlist[] = {"source", "encoding", "errors", 0};
755 PyObject *arg = NULL;
756 const char *encoding = NULL;
757 const char *errors = NULL;
758 Py_ssize_t count;
759 PyObject *it;
760 PyObject *(*iternext)(PyObject *);
761
762 if (Py_SIZE(self) != 0) {
763 /* Empty previous contents (yes, do this first of all!) */
764 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
765 return -1;
766 }
767
768 /* Parse arguments */
Neal Norwitzc86b54c2008-07-20 19:35:23 +0000769 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes44720832008-05-26 13:01:01 +0000770 &arg, &encoding, &errors))
771 return -1;
772
773 /* Make a quick exit if no first argument */
774 if (arg == NULL) {
775 if (encoding != NULL || errors != NULL) {
776 PyErr_SetString(PyExc_TypeError,
777 "encoding or errors without sequence argument");
778 return -1;
779 }
780 return 0;
781 }
782
783 if (PyBytes_Check(arg)) {
784 PyObject *new, *encoded;
785 if (encoding != NULL) {
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300786 encoded = _PyCodec_EncodeText(arg, encoding, errors);
Christian Heimes44720832008-05-26 13:01:01 +0000787 if (encoded == NULL)
788 return -1;
789 assert(PyBytes_Check(encoded));
790 }
791 else {
792 encoded = arg;
793 Py_INCREF(arg);
794 }
Benjamin Petersond6720012009-04-18 15:31:34 +0000795 new = bytearray_iconcat(self, arg);
Christian Heimes44720832008-05-26 13:01:01 +0000796 Py_DECREF(encoded);
797 if (new == NULL)
798 return -1;
799 Py_DECREF(new);
800 return 0;
801 }
802
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000803#ifdef Py_USING_UNICODE
Christian Heimes44720832008-05-26 13:01:01 +0000804 if (PyUnicode_Check(arg)) {
805 /* Encode via the codec registry */
806 PyObject *encoded, *new;
807 if (encoding == NULL) {
808 PyErr_SetString(PyExc_TypeError,
809 "unicode argument without an encoding");
810 return -1;
811 }
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300812 encoded = _PyCodec_EncodeText(arg, encoding, errors);
Christian Heimes44720832008-05-26 13:01:01 +0000813 if (encoded == NULL)
814 return -1;
815 assert(PyBytes_Check(encoded));
Benjamin Petersond6720012009-04-18 15:31:34 +0000816 new = bytearray_iconcat(self, encoded);
Christian Heimes44720832008-05-26 13:01:01 +0000817 Py_DECREF(encoded);
818 if (new == NULL)
819 return -1;
820 Py_DECREF(new);
821 return 0;
822 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000823#endif
Christian Heimes44720832008-05-26 13:01:01 +0000824
825 /* If it's not unicode, there can't be encoding or errors */
826 if (encoding != NULL || errors != NULL) {
827 PyErr_SetString(PyExc_TypeError,
828 "encoding or errors without a string argument");
829 return -1;
830 }
831
832 /* Is it an int? */
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000833 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
834 if (count == -1 && PyErr_Occurred()) {
835 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes44720832008-05-26 13:01:01 +0000836 return -1;
Benjamin Petersonae530c22010-04-16 22:52:44 +0000837 PyErr_Clear();
Benjamin Peterson821a8ea2010-04-16 22:35:38 +0000838 }
839 else if (count < 0) {
840 PyErr_SetString(PyExc_ValueError, "negative count");
841 return -1;
842 }
843 else {
Christian Heimes44720832008-05-26 13:01:01 +0000844 if (count > 0) {
845 if (PyByteArray_Resize((PyObject *)self, count))
846 return -1;
847 memset(self->ob_bytes, 0, count);
848 }
849 return 0;
850 }
851
852 /* Use the buffer API */
853 if (PyObject_CheckBuffer(arg)) {
854 Py_ssize_t size;
855 Py_buffer view;
856 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
857 return -1;
858 size = view.len;
859 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
860 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
861 goto fail;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000862 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000863 return 0;
864 fail:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +0000865 PyBuffer_Release(&view);
Christian Heimes44720832008-05-26 13:01:01 +0000866 return -1;
867 }
868
869 /* XXX Optimize this if the arguments is a list, tuple */
870
871 /* Get the iterator */
872 it = PyObject_GetIter(arg);
873 if (it == NULL)
874 return -1;
875 iternext = *Py_TYPE(it)->tp_iternext;
876
877 /* Run the iterator to exhaustion */
878 for (;;) {
879 PyObject *item;
Georg Brandl3e758462008-07-16 23:10:05 +0000880 int rc, value;
Christian Heimes44720832008-05-26 13:01:01 +0000881
882 /* Get the next item */
883 item = iternext(it);
884 if (item == NULL) {
885 if (PyErr_Occurred()) {
886 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
887 goto error;
888 PyErr_Clear();
889 }
890 break;
891 }
892
893 /* Interpret it as an int (__index__) */
Georg Brandl3e758462008-07-16 23:10:05 +0000894 rc = _getbytevalue(item, &value);
Christian Heimes44720832008-05-26 13:01:01 +0000895 Py_DECREF(item);
Georg Brandl3e758462008-07-16 23:10:05 +0000896 if (!rc)
Christian Heimes44720832008-05-26 13:01:01 +0000897 goto error;
898
Christian Heimes44720832008-05-26 13:01:01 +0000899 /* Append the byte */
Serhiy Storchakaab766352015-06-29 21:13:54 +0300900 if (Py_SIZE(self) + 1 < self->ob_alloc) {
Christian Heimes44720832008-05-26 13:01:01 +0000901 Py_SIZE(self)++;
Serhiy Storchakaab766352015-06-29 21:13:54 +0300902 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
903 }
Christian Heimes44720832008-05-26 13:01:01 +0000904 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
905 goto error;
906 self->ob_bytes[Py_SIZE(self)-1] = value;
907 }
908
909 /* Clean up and return success */
910 Py_DECREF(it);
911 return 0;
912
913 error:
914 /* Error handling when it != NULL */
915 Py_DECREF(it);
916 return -1;
917}
918
919/* Mostly copied from string_repr, but without the
920 "smart quote" functionality. */
921static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +0000922bytearray_repr(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +0000923{
924 static const char *hexdigits = "0123456789abcdef";
925 const char *quote_prefix = "bytearray(b";
926 const char *quote_postfix = ")";
927 Py_ssize_t length = Py_SIZE(self);
928 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000929 size_t newsize;
Christian Heimes44720832008-05-26 13:01:01 +0000930 PyObject *v;
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000931 if (length > (PY_SSIZE_T_MAX - 14) / 4) {
Christian Heimes44720832008-05-26 13:01:01 +0000932 PyErr_SetString(PyExc_OverflowError,
933 "bytearray object is too large to make repr");
934 return NULL;
935 }
Mark Dickinson2d7911e2010-02-14 12:31:26 +0000936 newsize = 14 + 4 * length;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000937 v = PyString_FromStringAndSize(NULL, newsize);
Christian Heimes44720832008-05-26 13:01:01 +0000938 if (v == NULL) {
939 return NULL;
940 }
941 else {
942 register Py_ssize_t i;
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000943 register char c;
944 register char *p;
Christian Heimes44720832008-05-26 13:01:01 +0000945 int quote;
946
947 /* Figure out which quote to use; single is preferred */
948 quote = '\'';
949 {
950 char *test, *start;
951 start = PyByteArray_AS_STRING(self);
952 for (test = start; test < start+length; ++test) {
953 if (*test == '"') {
954 quote = '\''; /* back to single */
955 goto decided;
956 }
957 else if (*test == '\'')
958 quote = '"';
959 }
960 decided:
961 ;
962 }
963
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000964 p = PyString_AS_STRING(v);
Christian Heimes44720832008-05-26 13:01:01 +0000965 while (*quote_prefix)
966 *p++ = *quote_prefix++;
967 *p++ = quote;
968
969 for (i = 0; i < length; i++) {
970 /* There's at least enough room for a hex escape
971 and a closing quote. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000972 assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
Christian Heimes44720832008-05-26 13:01:01 +0000973 c = self->ob_bytes[i];
974 if (c == '\'' || c == '\\')
975 *p++ = '\\', *p++ = c;
976 else if (c == '\t')
977 *p++ = '\\', *p++ = 't';
978 else if (c == '\n')
979 *p++ = '\\', *p++ = 'n';
980 else if (c == '\r')
981 *p++ = '\\', *p++ = 'r';
982 else if (c == 0)
983 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
984 else if (c < ' ' || c >= 0x7f) {
985 *p++ = '\\';
986 *p++ = 'x';
987 *p++ = hexdigits[(c & 0xf0) >> 4];
988 *p++ = hexdigits[c & 0xf];
989 }
990 else
991 *p++ = c;
992 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +0000993 assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
Christian Heimes44720832008-05-26 13:01:01 +0000994 *p++ = quote;
995 while (*quote_postfix) {
996 *p++ = *quote_postfix++;
997 }
998 *p = '\0';
Kristján Valur Jónssonbe580f22014-04-25 09:51:21 +0000999 /* v is cleared on error */
1000 (void)_PyString_Resize(&v, (p - PyString_AS_STRING(v)));
Christian Heimes44720832008-05-26 13:01:01 +00001001 return v;
1002 }
1003}
1004
1005static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001006bytearray_str(PyObject *op)
Christian Heimes44720832008-05-26 13:01:01 +00001007{
1008#if 0
1009 if (Py_BytesWarningFlag) {
1010 if (PyErr_WarnEx(PyExc_BytesWarning,
1011 "str() on a bytearray instance", 1))
1012 return NULL;
1013 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001014 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes44720832008-05-26 13:01:01 +00001015#endif
1016 return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
1017}
1018
1019static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001020bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes44720832008-05-26 13:01:01 +00001021{
1022 Py_ssize_t self_size, other_size;
1023 Py_buffer self_bytes, other_bytes;
1024 PyObject *res;
1025 Py_ssize_t minsize;
Serhiy Storchaka5127ed72015-05-30 17:45:12 +03001026 int cmp, rc;
Christian Heimes44720832008-05-26 13:01:01 +00001027
1028 /* Bytes can be compared to anything that supports the (binary)
1029 buffer API. Except that a comparison with Unicode is always an
1030 error, even if the comparison is for equality. */
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001031#ifdef Py_USING_UNICODE
Serhiy Storchaka5127ed72015-05-30 17:45:12 +03001032 rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type);
1033 if (!rc)
1034 rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type);
1035 if (rc < 0)
1036 return NULL;
1037 if (rc) {
Christian Heimes44720832008-05-26 13:01:01 +00001038 if (Py_BytesWarningFlag && op == Py_EQ) {
1039 if (PyErr_WarnEx(PyExc_BytesWarning,
Ezio Melottid2342082010-01-14 11:34:10 +00001040 "Comparison between bytearray and string", 1))
Christian Heimes44720832008-05-26 13:01:01 +00001041 return NULL;
1042 }
1043
1044 Py_INCREF(Py_NotImplemented);
1045 return Py_NotImplemented;
1046 }
Benjamin Peterson78821dd2009-01-25 17:15:10 +00001047#endif
Christian Heimes44720832008-05-26 13:01:01 +00001048
1049 self_size = _getbuffer(self, &self_bytes);
1050 if (self_size < 0) {
1051 PyErr_Clear();
1052 Py_INCREF(Py_NotImplemented);
1053 return Py_NotImplemented;
1054 }
1055
1056 other_size = _getbuffer(other, &other_bytes);
1057 if (other_size < 0) {
1058 PyErr_Clear();
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001059 PyBuffer_Release(&self_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001060 Py_INCREF(Py_NotImplemented);
1061 return Py_NotImplemented;
1062 }
1063
1064 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1065 /* Shortcut: if the lengths differ, the objects differ */
1066 cmp = (op == Py_NE);
1067 }
1068 else {
1069 minsize = self_size;
1070 if (other_size < minsize)
1071 minsize = other_size;
1072
1073 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1074 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1075
1076 if (cmp == 0) {
1077 if (self_size < other_size)
1078 cmp = -1;
1079 else if (self_size > other_size)
1080 cmp = 1;
1081 }
1082
1083 switch (op) {
1084 case Py_LT: cmp = cmp < 0; break;
1085 case Py_LE: cmp = cmp <= 0; break;
1086 case Py_EQ: cmp = cmp == 0; break;
1087 case Py_NE: cmp = cmp != 0; break;
1088 case Py_GT: cmp = cmp > 0; break;
1089 case Py_GE: cmp = cmp >= 0; break;
1090 }
1091 }
1092
1093 res = cmp ? Py_True : Py_False;
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001094 PyBuffer_Release(&self_bytes);
1095 PyBuffer_Release(&other_bytes);
Christian Heimes44720832008-05-26 13:01:01 +00001096 Py_INCREF(res);
1097 return res;
1098}
1099
1100static void
Benjamin Petersond6720012009-04-18 15:31:34 +00001101bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes44720832008-05-26 13:01:01 +00001102{
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001103 if (self->ob_exports > 0) {
1104 PyErr_SetString(PyExc_SystemError,
Georg Brandl517cfdc2009-04-05 13:16:35 +00001105 "deallocated bytearray object has exported buffers");
Benjamin Peterson9c1f7b22009-03-08 00:21:17 +00001106 PyErr_Print();
1107 }
Christian Heimes44720832008-05-26 13:01:01 +00001108 if (self->ob_bytes != 0) {
1109 PyMem_Free(self->ob_bytes);
1110 }
1111 Py_TYPE(self)->tp_free((PyObject *)self);
1112}
1113
1114
1115/* -------------------------------------------------------------------- */
1116/* Methods */
1117
1118#define STRINGLIB_CHAR char
Christian Heimes44720832008-05-26 13:01:01 +00001119#define STRINGLIB_LEN PyByteArray_GET_SIZE
1120#define STRINGLIB_STR PyByteArray_AS_STRING
1121#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrou64672132010-01-13 07:55:48 +00001122#define STRINGLIB_ISSPACE Py_ISSPACE
1123#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes44720832008-05-26 13:01:01 +00001124#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1125#define STRINGLIB_MUTABLE 1
1126
1127#include "stringlib/fastsearch.h"
1128#include "stringlib/count.h"
1129#include "stringlib/find.h"
1130#include "stringlib/partition.h"
Antoine Pitrou64672132010-01-13 07:55:48 +00001131#include "stringlib/split.h"
Christian Heimes44720832008-05-26 13:01:01 +00001132#include "stringlib/ctype.h"
1133#include "stringlib/transmogrify.h"
1134
1135
1136/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1137were copied from the old char* style string object. */
1138
Antoine Pitrou64672132010-01-13 07:55:48 +00001139/* helper macro to fixup start/end slice values */
1140#define ADJUST_INDICES(start, end, len) \
1141 if (end > len) \
1142 end = len; \
1143 else if (end < 0) { \
1144 end += len; \
1145 if (end < 0) \
1146 end = 0; \
1147 } \
1148 if (start < 0) { \
1149 start += len; \
1150 if (start < 0) \
1151 start = 0; \
1152 }
Christian Heimes44720832008-05-26 13:01:01 +00001153
1154Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Petersond6720012009-04-18 15:31:34 +00001155bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes44720832008-05-26 13:01:01 +00001156{
1157 PyObject *subobj;
1158 Py_buffer subbuf;
1159 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1160 Py_ssize_t res;
1161
Jesus Cea44e81682011-04-20 16:39:15 +02001162 if (!stringlib_parse_args_finds("find/rfind/index/rindex",
1163 args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001164 return -2;
1165 if (_getbuffer(subobj, &subbuf) < 0)
1166 return -2;
1167 if (dir > 0)
1168 res = stringlib_find_slice(
1169 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1170 subbuf.buf, subbuf.len, start, end);
1171 else
1172 res = stringlib_rfind_slice(
1173 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1174 subbuf.buf, subbuf.len, start, end);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001175 PyBuffer_Release(&subbuf);
Christian Heimes44720832008-05-26 13:01:01 +00001176 return res;
1177}
1178
1179PyDoc_STRVAR(find__doc__,
1180"B.find(sub [,start [,end]]) -> int\n\
1181\n\
1182Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran5e3a19d2011-07-27 23:36:51 +08001183such that sub is contained within B[start,end]. Optional\n\
Christian Heimes44720832008-05-26 13:01:01 +00001184arguments start and end are interpreted as in slice notation.\n\
1185\n\
1186Return -1 on failure.");
1187
1188static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001189bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001190{
Benjamin Petersond6720012009-04-18 15:31:34 +00001191 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001192 if (result == -2)
1193 return NULL;
1194 return PyInt_FromSsize_t(result);
1195}
1196
1197PyDoc_STRVAR(count__doc__,
1198"B.count(sub [,start [,end]]) -> int\n\
1199\n\
1200Return the number of non-overlapping occurrences of subsection sub in\n\
1201bytes B[start:end]. Optional arguments start and end are interpreted\n\
1202as in slice notation.");
1203
1204static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001205bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001206{
1207 PyObject *sub_obj;
1208 const char *str = PyByteArray_AS_STRING(self);
1209 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1210 Py_buffer vsub;
1211 PyObject *count_obj;
1212
Jesus Cea44e81682011-04-20 16:39:15 +02001213 if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001214 return NULL;
1215
1216 if (_getbuffer(sub_obj, &vsub) < 0)
1217 return NULL;
1218
Antoine Pitrou64672132010-01-13 07:55:48 +00001219 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes44720832008-05-26 13:01:01 +00001220
1221 count_obj = PyInt_FromSsize_t(
Antoine Pitrou64672132010-01-13 07:55:48 +00001222 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
Christian Heimes44720832008-05-26 13:01:01 +00001223 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001224 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00001225 return count_obj;
1226}
1227
1228
1229PyDoc_STRVAR(index__doc__,
1230"B.index(sub [,start [,end]]) -> int\n\
1231\n\
1232Like B.find() but raise ValueError when the subsection is not found.");
1233
1234static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001235bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001236{
Benjamin Petersond6720012009-04-18 15:31:34 +00001237 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001238 if (result == -2)
1239 return NULL;
1240 if (result == -1) {
1241 PyErr_SetString(PyExc_ValueError,
1242 "subsection not found");
1243 return NULL;
1244 }
1245 return PyInt_FromSsize_t(result);
1246}
1247
1248
1249PyDoc_STRVAR(rfind__doc__,
1250"B.rfind(sub [,start [,end]]) -> int\n\
1251\n\
1252Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran5e3a19d2011-07-27 23:36:51 +08001253such that sub is contained within B[start,end]. Optional\n\
Christian Heimes44720832008-05-26 13:01:01 +00001254arguments start and end are interpreted as in slice notation.\n\
1255\n\
1256Return -1 on failure.");
1257
1258static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001259bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001260{
Benjamin Petersond6720012009-04-18 15:31:34 +00001261 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001262 if (result == -2)
1263 return NULL;
1264 return PyInt_FromSsize_t(result);
1265}
1266
1267
1268PyDoc_STRVAR(rindex__doc__,
1269"B.rindex(sub [,start [,end]]) -> int\n\
1270\n\
1271Like B.rfind() but raise ValueError when the subsection is not found.");
1272
1273static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001274bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001275{
Benjamin Petersond6720012009-04-18 15:31:34 +00001276 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001277 if (result == -2)
1278 return NULL;
1279 if (result == -1) {
1280 PyErr_SetString(PyExc_ValueError,
1281 "subsection not found");
1282 return NULL;
1283 }
1284 return PyInt_FromSsize_t(result);
1285}
1286
1287
1288static int
Benjamin Petersond6720012009-04-18 15:31:34 +00001289bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00001290{
1291 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1292 if (ival == -1 && PyErr_Occurred()) {
1293 Py_buffer varg;
1294 int pos;
1295 PyErr_Clear();
1296 if (_getbuffer(arg, &varg) < 0)
1297 return -1;
1298 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1299 varg.buf, varg.len, 0);
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001300 PyBuffer_Release(&varg);
Christian Heimes44720832008-05-26 13:01:01 +00001301 return pos >= 0;
1302 }
1303 if (ival < 0 || ival >= 256) {
1304 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1305 return -1;
1306 }
1307
1308 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1309}
1310
1311
1312/* Matches the end (direction >= 0) or start (direction < 0) of self
1313 * against substr, using the start and end arguments. Returns
1314 * -1 on error, 0 if not found and 1 if found.
1315 */
1316Py_LOCAL(int)
Benjamin Petersond6720012009-04-18 15:31:34 +00001317_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes44720832008-05-26 13:01:01 +00001318 Py_ssize_t end, int direction)
1319{
1320 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1321 const char* str;
1322 Py_buffer vsubstr;
1323 int rv = 0;
1324
1325 str = PyByteArray_AS_STRING(self);
1326
1327 if (_getbuffer(substr, &vsubstr) < 0)
1328 return -1;
1329
Antoine Pitrou64672132010-01-13 07:55:48 +00001330 ADJUST_INDICES(start, end, len);
Christian Heimes44720832008-05-26 13:01:01 +00001331
1332 if (direction < 0) {
1333 /* startswith */
1334 if (start+vsubstr.len > len) {
1335 goto done;
1336 }
1337 } else {
1338 /* endswith */
1339 if (end-start < vsubstr.len || start > len) {
1340 goto done;
1341 }
1342
1343 if (end-vsubstr.len > start)
1344 start = end - vsubstr.len;
1345 }
1346 if (end-start >= vsubstr.len)
1347 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1348
1349done:
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001350 PyBuffer_Release(&vsubstr);
Christian Heimes44720832008-05-26 13:01:01 +00001351 return rv;
1352}
1353
1354
1355PyDoc_STRVAR(startswith__doc__,
1356"B.startswith(prefix [,start [,end]]) -> bool\n\
1357\n\
1358Return True if B starts with the specified prefix, False otherwise.\n\
1359With optional start, test B beginning at that position.\n\
1360With optional end, stop comparing B at that position.\n\
1361prefix can also be a tuple of strings to try.");
1362
1363static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001364bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001365{
1366 Py_ssize_t start = 0;
1367 Py_ssize_t end = PY_SSIZE_T_MAX;
1368 PyObject *subobj;
1369 int result;
1370
Jesus Cea44e81682011-04-20 16:39:15 +02001371 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001372 return NULL;
1373 if (PyTuple_Check(subobj)) {
1374 Py_ssize_t i;
1375 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001376 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001377 PyTuple_GET_ITEM(subobj, i),
1378 start, end, -1);
1379 if (result == -1)
1380 return NULL;
1381 else if (result) {
1382 Py_RETURN_TRUE;
1383 }
1384 }
1385 Py_RETURN_FALSE;
1386 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001387 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Christian Heimes44720832008-05-26 13:01:01 +00001388 if (result == -1)
1389 return NULL;
1390 else
1391 return PyBool_FromLong(result);
1392}
1393
1394PyDoc_STRVAR(endswith__doc__,
1395"B.endswith(suffix [,start [,end]]) -> bool\n\
1396\n\
1397Return True if B ends with the specified suffix, False otherwise.\n\
1398With optional start, test B beginning at that position.\n\
1399With optional end, stop comparing B at that position.\n\
1400suffix can also be a tuple of strings to try.");
1401
1402static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001403bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001404{
1405 Py_ssize_t start = 0;
1406 Py_ssize_t end = PY_SSIZE_T_MAX;
1407 PyObject *subobj;
1408 int result;
1409
Jesus Cea44e81682011-04-20 16:39:15 +02001410 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes44720832008-05-26 13:01:01 +00001411 return NULL;
1412 if (PyTuple_Check(subobj)) {
1413 Py_ssize_t i;
1414 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Petersond6720012009-04-18 15:31:34 +00001415 result = _bytearray_tailmatch(self,
Christian Heimes44720832008-05-26 13:01:01 +00001416 PyTuple_GET_ITEM(subobj, i),
1417 start, end, +1);
1418 if (result == -1)
1419 return NULL;
1420 else if (result) {
1421 Py_RETURN_TRUE;
1422 }
1423 }
1424 Py_RETURN_FALSE;
1425 }
Benjamin Petersond6720012009-04-18 15:31:34 +00001426 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Christian Heimes44720832008-05-26 13:01:01 +00001427 if (result == -1)
1428 return NULL;
1429 else
1430 return PyBool_FromLong(result);
1431}
1432
1433
1434PyDoc_STRVAR(translate__doc__,
1435"B.translate(table[, deletechars]) -> bytearray\n\
1436\n\
1437Return a copy of B, where all characters occurring in the\n\
1438optional argument deletechars are removed, and the remaining\n\
1439characters have been mapped through the given translation\n\
1440table, which must be a bytes object of length 256.");
1441
1442static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00001443bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00001444{
1445 register char *input, *output;
1446 register const char *table;
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001447 register Py_ssize_t i, c;
Christian Heimes44720832008-05-26 13:01:01 +00001448 PyObject *input_obj = (PyObject*)self;
1449 const char *output_start;
1450 Py_ssize_t inlen;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001451 PyObject *result = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001452 int trans_table[256];
Georg Brandl6425a2f2008-12-28 11:54:53 +00001453 PyObject *tableobj = NULL, *delobj = NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001454 Py_buffer vtable, vdel;
1455
1456 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1457 &tableobj, &delobj))
1458 return NULL;
1459
Georg Brandl6425a2f2008-12-28 11:54:53 +00001460 if (tableobj == Py_None) {
1461 table = NULL;
1462 tableobj = NULL;
1463 } else if (_getbuffer(tableobj, &vtable) < 0) {
Christian Heimes44720832008-05-26 13:01:01 +00001464 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001465 } else {
1466 if (vtable.len != 256) {
1467 PyErr_SetString(PyExc_ValueError,
1468 "translation table must be 256 characters long");
Georg Brandlec812ca2009-07-22 11:57:15 +00001469 PyBuffer_Release(&vtable);
1470 return NULL;
Georg Brandl6425a2f2008-12-28 11:54:53 +00001471 }
1472 table = (const char*)vtable.buf;
Christian Heimes44720832008-05-26 13:01:01 +00001473 }
1474
1475 if (delobj != NULL) {
1476 if (_getbuffer(delobj, &vdel) < 0) {
Georg Brandlec812ca2009-07-22 11:57:15 +00001477 if (tableobj != NULL)
1478 PyBuffer_Release(&vtable);
1479 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00001480 }
1481 }
1482 else {
1483 vdel.buf = NULL;
1484 vdel.len = 0;
1485 }
1486
Christian Heimes44720832008-05-26 13:01:01 +00001487 inlen = PyByteArray_GET_SIZE(input_obj);
1488 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1489 if (result == NULL)
1490 goto done;
1491 output_start = output = PyByteArray_AsString(result);
1492 input = PyByteArray_AS_STRING(input_obj);
1493
Georg Brandl6425a2f2008-12-28 11:54:53 +00001494 if (vdel.len == 0 && table != NULL) {
Christian Heimes44720832008-05-26 13:01:01 +00001495 /* If no deletions are required, use faster code */
1496 for (i = inlen; --i >= 0; ) {
1497 c = Py_CHARMASK(*input++);
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001498 *output++ = table[c];
Christian Heimes44720832008-05-26 13:01:01 +00001499 }
Christian Heimes44720832008-05-26 13:01:01 +00001500 goto done;
1501 }
Georg Brandl6425a2f2008-12-28 11:54:53 +00001502
1503 if (table == NULL) {
1504 for (i = 0; i < 256; i++)
1505 trans_table[i] = Py_CHARMASK(i);
1506 } else {
1507 for (i = 0; i < 256; i++)
1508 trans_table[i] = Py_CHARMASK(table[i]);
1509 }
Christian Heimes44720832008-05-26 13:01:01 +00001510
1511 for (i = 0; i < vdel.len; i++)
1512 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1513
1514 for (i = inlen; --i >= 0; ) {
1515 c = Py_CHARMASK(*input++);
1516 if (trans_table[c] != -1)
1517 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1518 continue;
Christian Heimes44720832008-05-26 13:01:01 +00001519 }
1520 /* Fix the size of the resulting string */
1521 if (inlen > 0)
1522 PyByteArray_Resize(result, output - output_start);
1523
1524done:
Georg Brandl6425a2f2008-12-28 11:54:53 +00001525 if (tableobj != NULL)
1526 PyBuffer_Release(&vtable);
Christian Heimes44720832008-05-26 13:01:01 +00001527 if (delobj != NULL)
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00001528 PyBuffer_Release(&vdel);
Christian Heimes44720832008-05-26 13:01:01 +00001529 return result;
1530}
1531
1532
Christian Heimes44720832008-05-26 13:01:01 +00001533/* find and count characters and substrings */
1534
1535#define findchar(target, target_len, c) \
1536 ((char *)memchr((const void *)(target), c, target_len))
1537
Christian Heimes44720832008-05-26 13:01:01 +00001538
Benjamin Peterson46cc6d12008-11-19 21:49:09 +00001539/* Bytes ops must return a string, create a copy */
Christian Heimes44720832008-05-26 13:01:01 +00001540Py_LOCAL(PyByteArrayObject *)
1541return_self(PyByteArrayObject *self)
1542{
Christian Heimes44720832008-05-26 13:01:01 +00001543 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1544 PyByteArray_AS_STRING(self),
1545 PyByteArray_GET_SIZE(self));
1546}
1547
1548Py_LOCAL_INLINE(Py_ssize_t)
1549countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1550{
1551 Py_ssize_t count=0;
1552 const char *start=target;
1553 const char *end=target+target_len;
1554
1555 while ( (start=findchar(start, end-start, c)) != NULL ) {
1556 count++;
1557 if (count >= maxcount)
1558 break;
1559 start += 1;
1560 }
1561 return count;
1562}
1563
Christian Heimes44720832008-05-26 13:01:01 +00001564
1565/* Algorithms for different cases of string replacement */
1566
1567/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1568Py_LOCAL(PyByteArrayObject *)
1569replace_interleave(PyByteArrayObject *self,
1570 const char *to_s, Py_ssize_t to_len,
1571 Py_ssize_t maxcount)
1572{
1573 char *self_s, *result_s;
1574 Py_ssize_t self_len, result_len;
1575 Py_ssize_t count, i, product;
1576 PyByteArrayObject *result;
1577
1578 self_len = PyByteArray_GET_SIZE(self);
1579
1580 /* 1 at the end plus 1 after every character */
1581 count = self_len+1;
1582 if (maxcount < count)
1583 count = maxcount;
1584
1585 /* Check for overflow */
1586 /* result_len = count * to_len + self_len; */
1587 product = count * to_len;
1588 if (product / to_len != count) {
1589 PyErr_SetString(PyExc_OverflowError,
1590 "replace string is too long");
1591 return NULL;
1592 }
1593 result_len = product + self_len;
1594 if (result_len < 0) {
1595 PyErr_SetString(PyExc_OverflowError,
1596 "replace string is too long");
1597 return NULL;
1598 }
1599
1600 if (! (result = (PyByteArrayObject *)
1601 PyByteArray_FromStringAndSize(NULL, result_len)) )
1602 return NULL;
1603
1604 self_s = PyByteArray_AS_STRING(self);
1605 result_s = PyByteArray_AS_STRING(result);
1606
1607 /* TODO: special case single character, which doesn't need memcpy */
1608
1609 /* Lay the first one down (guaranteed this will occur) */
1610 Py_MEMCPY(result_s, to_s, to_len);
1611 result_s += to_len;
1612 count -= 1;
1613
1614 for (i=0; i<count; i++) {
1615 *result_s++ = *self_s++;
1616 Py_MEMCPY(result_s, to_s, to_len);
1617 result_s += to_len;
1618 }
1619
1620 /* Copy the rest of the original string */
1621 Py_MEMCPY(result_s, self_s, self_len-i);
1622
1623 return result;
1624}
1625
1626/* Special case for deleting a single character */
1627/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1628Py_LOCAL(PyByteArrayObject *)
1629replace_delete_single_character(PyByteArrayObject *self,
1630 char from_c, Py_ssize_t maxcount)
1631{
1632 char *self_s, *result_s;
1633 char *start, *next, *end;
1634 Py_ssize_t self_len, result_len;
1635 Py_ssize_t count;
1636 PyByteArrayObject *result;
1637
1638 self_len = PyByteArray_GET_SIZE(self);
1639 self_s = PyByteArray_AS_STRING(self);
1640
1641 count = countchar(self_s, self_len, from_c, maxcount);
1642 if (count == 0) {
1643 return return_self(self);
1644 }
1645
1646 result_len = self_len - count; /* from_len == 1 */
1647 assert(result_len>=0);
1648
1649 if ( (result = (PyByteArrayObject *)
1650 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1651 return NULL;
1652 result_s = PyByteArray_AS_STRING(result);
1653
1654 start = self_s;
1655 end = self_s + self_len;
1656 while (count-- > 0) {
1657 next = findchar(start, end-start, from_c);
1658 if (next == NULL)
1659 break;
1660 Py_MEMCPY(result_s, start, next-start);
1661 result_s += (next-start);
1662 start = next+1;
1663 }
1664 Py_MEMCPY(result_s, start, end-start);
1665
1666 return result;
1667}
1668
1669/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1670
1671Py_LOCAL(PyByteArrayObject *)
1672replace_delete_substring(PyByteArrayObject *self,
1673 const char *from_s, Py_ssize_t from_len,
1674 Py_ssize_t maxcount)
1675{
1676 char *self_s, *result_s;
1677 char *start, *next, *end;
1678 Py_ssize_t self_len, result_len;
1679 Py_ssize_t count, offset;
1680 PyByteArrayObject *result;
1681
1682 self_len = PyByteArray_GET_SIZE(self);
1683 self_s = PyByteArray_AS_STRING(self);
1684
Antoine Pitrou64672132010-01-13 07:55:48 +00001685 count = stringlib_count(self_s, self_len,
1686 from_s, from_len,
1687 maxcount);
Christian Heimes44720832008-05-26 13:01:01 +00001688
1689 if (count == 0) {
1690 /* no matches */
1691 return return_self(self);
1692 }
1693
1694 result_len = self_len - (count * from_len);
1695 assert (result_len>=0);
1696
1697 if ( (result = (PyByteArrayObject *)
1698 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1699 return NULL;
1700
1701 result_s = PyByteArray_AS_STRING(result);
1702
1703 start = self_s;
1704 end = self_s + self_len;
1705 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001706 offset = stringlib_find(start, end-start,
1707 from_s, from_len,
1708 0);
Christian Heimes44720832008-05-26 13:01:01 +00001709 if (offset == -1)
1710 break;
1711 next = start + offset;
1712
1713 Py_MEMCPY(result_s, start, next-start);
1714
1715 result_s += (next-start);
1716 start = next+from_len;
1717 }
1718 Py_MEMCPY(result_s, start, end-start);
1719 return result;
1720}
1721
1722/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1723Py_LOCAL(PyByteArrayObject *)
1724replace_single_character_in_place(PyByteArrayObject *self,
1725 char from_c, char to_c,
1726 Py_ssize_t maxcount)
1727{
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001728 char *self_s, *result_s, *start, *end, *next;
1729 Py_ssize_t self_len;
1730 PyByteArrayObject *result;
Christian Heimes44720832008-05-26 13:01:01 +00001731
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001732 /* The result string will be the same size */
1733 self_s = PyByteArray_AS_STRING(self);
1734 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes44720832008-05-26 13:01:01 +00001735
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001736 next = findchar(self_s, self_len, from_c);
Christian Heimes44720832008-05-26 13:01:01 +00001737
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001738 if (next == NULL) {
1739 /* No matches; return the original bytes */
1740 return return_self(self);
1741 }
Christian Heimes44720832008-05-26 13:01:01 +00001742
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001743 /* Need to make a new bytes */
1744 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1745 if (result == NULL)
1746 return NULL;
1747 result_s = PyByteArray_AS_STRING(result);
1748 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes44720832008-05-26 13:01:01 +00001749
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001750 /* change everything in-place, starting with this one */
1751 start = result_s + (next-self_s);
1752 *start = to_c;
1753 start++;
1754 end = result_s + self_len;
Christian Heimes44720832008-05-26 13:01:01 +00001755
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001756 while (--maxcount > 0) {
1757 next = findchar(start, end-start, from_c);
1758 if (next == NULL)
1759 break;
1760 *next = to_c;
1761 start = next+1;
1762 }
Christian Heimes44720832008-05-26 13:01:01 +00001763
Antoine Pitrou619f16e2010-06-09 16:24:00 +00001764 return result;
Christian Heimes44720832008-05-26 13:01:01 +00001765}
1766
1767/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1768Py_LOCAL(PyByteArrayObject *)
1769replace_substring_in_place(PyByteArrayObject *self,
1770 const char *from_s, Py_ssize_t from_len,
1771 const char *to_s, Py_ssize_t to_len,
1772 Py_ssize_t maxcount)
1773{
1774 char *result_s, *start, *end;
1775 char *self_s;
1776 Py_ssize_t self_len, offset;
1777 PyByteArrayObject *result;
1778
1779 /* The result bytes will be the same size */
1780
1781 self_s = PyByteArray_AS_STRING(self);
1782 self_len = PyByteArray_GET_SIZE(self);
1783
Antoine Pitrou64672132010-01-13 07:55:48 +00001784 offset = stringlib_find(self_s, self_len,
1785 from_s, from_len,
1786 0);
Christian Heimes44720832008-05-26 13:01:01 +00001787 if (offset == -1) {
1788 /* No matches; return the original bytes */
1789 return return_self(self);
1790 }
1791
1792 /* Need to make a new bytes */
1793 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1794 if (result == NULL)
1795 return NULL;
1796 result_s = PyByteArray_AS_STRING(result);
1797 Py_MEMCPY(result_s, self_s, self_len);
1798
1799 /* change everything in-place, starting with this one */
1800 start = result_s + offset;
1801 Py_MEMCPY(start, to_s, from_len);
1802 start += from_len;
1803 end = result_s + self_len;
1804
1805 while ( --maxcount > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001806 offset = stringlib_find(start, end-start,
1807 from_s, from_len,
1808 0);
Christian Heimes44720832008-05-26 13:01:01 +00001809 if (offset==-1)
1810 break;
1811 Py_MEMCPY(start+offset, to_s, from_len);
1812 start += offset+from_len;
1813 }
1814
1815 return result;
1816}
1817
1818/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1819Py_LOCAL(PyByteArrayObject *)
1820replace_single_character(PyByteArrayObject *self,
1821 char from_c,
1822 const char *to_s, Py_ssize_t to_len,
1823 Py_ssize_t maxcount)
1824{
1825 char *self_s, *result_s;
1826 char *start, *next, *end;
1827 Py_ssize_t self_len, result_len;
1828 Py_ssize_t count, product;
1829 PyByteArrayObject *result;
1830
1831 self_s = PyByteArray_AS_STRING(self);
1832 self_len = PyByteArray_GET_SIZE(self);
1833
1834 count = countchar(self_s, self_len, from_c, maxcount);
1835 if (count == 0) {
1836 /* no matches, return unchanged */
1837 return return_self(self);
1838 }
1839
1840 /* use the difference between current and new, hence the "-1" */
1841 /* result_len = self_len + count * (to_len-1) */
1842 product = count * (to_len-1);
1843 if (product / (to_len-1) != count) {
1844 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1845 return NULL;
1846 }
1847 result_len = self_len + product;
1848 if (result_len < 0) {
1849 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1850 return NULL;
1851 }
1852
1853 if ( (result = (PyByteArrayObject *)
1854 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1855 return NULL;
1856 result_s = PyByteArray_AS_STRING(result);
1857
1858 start = self_s;
1859 end = self_s + self_len;
1860 while (count-- > 0) {
1861 next = findchar(start, end-start, from_c);
1862 if (next == NULL)
1863 break;
1864
1865 if (next == start) {
1866 /* replace with the 'to' */
1867 Py_MEMCPY(result_s, to_s, to_len);
1868 result_s += to_len;
1869 start += 1;
1870 } else {
1871 /* copy the unchanged old then the 'to' */
1872 Py_MEMCPY(result_s, start, next-start);
1873 result_s += (next-start);
1874 Py_MEMCPY(result_s, to_s, to_len);
1875 result_s += to_len;
1876 start = next+1;
1877 }
1878 }
1879 /* Copy the remainder of the remaining bytes */
1880 Py_MEMCPY(result_s, start, end-start);
1881
1882 return result;
1883}
1884
1885/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1886Py_LOCAL(PyByteArrayObject *)
1887replace_substring(PyByteArrayObject *self,
1888 const char *from_s, Py_ssize_t from_len,
1889 const char *to_s, Py_ssize_t to_len,
1890 Py_ssize_t maxcount)
1891{
1892 char *self_s, *result_s;
1893 char *start, *next, *end;
1894 Py_ssize_t self_len, result_len;
1895 Py_ssize_t count, offset, product;
1896 PyByteArrayObject *result;
1897
1898 self_s = PyByteArray_AS_STRING(self);
1899 self_len = PyByteArray_GET_SIZE(self);
1900
Antoine Pitrou64672132010-01-13 07:55:48 +00001901 count = stringlib_count(self_s, self_len,
1902 from_s, from_len,
1903 maxcount);
1904
Christian Heimes44720832008-05-26 13:01:01 +00001905 if (count == 0) {
1906 /* no matches, return unchanged */
1907 return return_self(self);
1908 }
1909
1910 /* Check for overflow */
1911 /* result_len = self_len + count * (to_len-from_len) */
1912 product = count * (to_len-from_len);
1913 if (product / (to_len-from_len) != count) {
1914 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1915 return NULL;
1916 }
1917 result_len = self_len + product;
1918 if (result_len < 0) {
1919 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1920 return NULL;
1921 }
1922
1923 if ( (result = (PyByteArrayObject *)
1924 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1925 return NULL;
1926 result_s = PyByteArray_AS_STRING(result);
1927
1928 start = self_s;
1929 end = self_s + self_len;
1930 while (count-- > 0) {
Antoine Pitrou64672132010-01-13 07:55:48 +00001931 offset = stringlib_find(start, end-start,
1932 from_s, from_len,
1933 0);
Christian Heimes44720832008-05-26 13:01:01 +00001934 if (offset == -1)
1935 break;
1936 next = start+offset;
1937 if (next == start) {
1938 /* replace with the 'to' */
1939 Py_MEMCPY(result_s, to_s, to_len);
1940 result_s += to_len;
1941 start += from_len;
1942 } else {
1943 /* copy the unchanged old then the 'to' */
1944 Py_MEMCPY(result_s, start, next-start);
1945 result_s += (next-start);
1946 Py_MEMCPY(result_s, to_s, to_len);
1947 result_s += to_len;
1948 start = next+from_len;
1949 }
1950 }
1951 /* Copy the remainder of the remaining bytes */
1952 Py_MEMCPY(result_s, start, end-start);
1953
1954 return result;
1955}
1956
1957
1958Py_LOCAL(PyByteArrayObject *)
1959replace(PyByteArrayObject *self,
1960 const char *from_s, Py_ssize_t from_len,
1961 const char *to_s, Py_ssize_t to_len,
1962 Py_ssize_t maxcount)
1963{
1964 if (maxcount < 0) {
1965 maxcount = PY_SSIZE_T_MAX;
1966 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1967 /* nothing to do; return the original bytes */
1968 return return_self(self);
1969 }
1970
1971 if (maxcount == 0 ||
1972 (from_len == 0 && to_len == 0)) {
1973 /* nothing to do; return the original bytes */
1974 return return_self(self);
1975 }
1976
1977 /* Handle zero-length special cases */
1978
1979 if (from_len == 0) {
1980 /* insert the 'to' bytes everywhere. */
1981 /* >>> "Python".replace("", ".") */
1982 /* '.P.y.t.h.o.n.' */
1983 return replace_interleave(self, to_s, to_len, maxcount);
1984 }
1985
1986 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1987 /* point for an empty self bytes to generate a non-empty bytes */
1988 /* Special case so the remaining code always gets a non-empty bytes */
1989 if (PyByteArray_GET_SIZE(self) == 0) {
1990 return return_self(self);
1991 }
1992
1993 if (to_len == 0) {
1994 /* delete all occurances of 'from' bytes */
1995 if (from_len == 1) {
1996 return replace_delete_single_character(
1997 self, from_s[0], maxcount);
1998 } else {
1999 return replace_delete_substring(self, from_s, from_len, maxcount);
2000 }
2001 }
2002
2003 /* Handle special case where both bytes have the same length */
2004
2005 if (from_len == to_len) {
2006 if (from_len == 1) {
2007 return replace_single_character_in_place(
2008 self,
2009 from_s[0],
2010 to_s[0],
2011 maxcount);
2012 } else {
2013 return replace_substring_in_place(
2014 self, from_s, from_len, to_s, to_len, maxcount);
2015 }
2016 }
2017
2018 /* Otherwise use the more generic algorithms */
2019 if (from_len == 1) {
2020 return replace_single_character(self, from_s[0],
2021 to_s, to_len, maxcount);
2022 } else {
2023 /* len('from')>=2, len('to')>=1 */
2024 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2025 }
2026}
2027
2028
2029PyDoc_STRVAR(replace__doc__,
2030"B.replace(old, new[, count]) -> bytes\n\
2031\n\
2032Return a copy of B with all occurrences of subsection\n\
2033old replaced by new. If the optional argument count is\n\
2034given, only the first count occurrences are replaced.");
2035
2036static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002037bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002038{
2039 Py_ssize_t count = -1;
2040 PyObject *from, *to, *res;
2041 Py_buffer vfrom, vto;
2042
2043 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2044 return NULL;
2045
2046 if (_getbuffer(from, &vfrom) < 0)
2047 return NULL;
2048 if (_getbuffer(to, &vto) < 0) {
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002049 PyBuffer_Release(&vfrom);
Christian Heimes44720832008-05-26 13:01:01 +00002050 return NULL;
2051 }
2052
2053 res = (PyObject *)replace((PyByteArrayObject *) self,
2054 vfrom.buf, vfrom.len,
2055 vto.buf, vto.len, count);
2056
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002057 PyBuffer_Release(&vfrom);
2058 PyBuffer_Release(&vto);
Christian Heimes44720832008-05-26 13:01:01 +00002059 return res;
2060}
2061
Christian Heimes44720832008-05-26 13:01:01 +00002062PyDoc_STRVAR(split__doc__,
2063"B.split([sep[, maxsplit]]) -> list of bytearray\n\
2064\n\
2065Return a list of the sections in B, using sep as the delimiter.\n\
2066If sep is not given, B is split on ASCII whitespace characters\n\
2067(space, tab, return, newline, formfeed, vertical tab).\n\
2068If maxsplit is given, at most maxsplit splits are done.");
2069
2070static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002071bytearray_split(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002072{
Antoine Pitrou64672132010-01-13 07:55:48 +00002073 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2074 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002075 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002076 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002077 Py_buffer vsub;
Christian Heimes44720832008-05-26 13:01:01 +00002078
2079 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2080 return NULL;
2081 if (maxsplit < 0)
2082 maxsplit = PY_SSIZE_T_MAX;
2083
2084 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002085 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002086
2087 if (_getbuffer(subobj, &vsub) < 0)
2088 return NULL;
2089 sub = vsub.buf;
2090 n = vsub.len;
2091
Antoine Pitrou64672132010-01-13 07:55:48 +00002092 list = stringlib_split(
2093 (PyObject*) self, s, len, sub, n, maxsplit
2094 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002095 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002096 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002097}
2098
2099PyDoc_STRVAR(partition__doc__,
2100"B.partition(sep) -> (head, sep, tail)\n\
2101\n\
2102Searches for the separator sep in B, and returns the part before it,\n\
2103the separator itself, and the part after it. If the separator is not\n\
2104found, returns B and two empty bytearray objects.");
2105
2106static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002107bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002108{
2109 PyObject *bytesep, *result;
2110
2111 bytesep = PyByteArray_FromObject(sep_obj);
2112 if (! bytesep)
2113 return NULL;
2114
2115 result = stringlib_partition(
2116 (PyObject*) self,
2117 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2118 bytesep,
2119 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2120 );
2121
2122 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002123 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002124}
2125
2126PyDoc_STRVAR(rpartition__doc__,
Ezio Melotti1fafaab2010-01-25 11:24:37 +00002127"B.rpartition(sep) -> (head, sep, tail)\n\
Christian Heimes44720832008-05-26 13:01:01 +00002128\n\
2129Searches for the separator sep in B, starting at the end of B,\n\
2130and returns the part before it, the separator itself, and the\n\
2131part after it. If the separator is not found, returns two empty\n\
2132bytearray objects and B.");
2133
2134static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002135bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
Christian Heimes44720832008-05-26 13:01:01 +00002136{
2137 PyObject *bytesep, *result;
2138
2139 bytesep = PyByteArray_FromObject(sep_obj);
2140 if (! bytesep)
2141 return NULL;
2142
2143 result = stringlib_rpartition(
2144 (PyObject*) self,
2145 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2146 bytesep,
2147 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2148 );
2149
2150 Py_DECREF(bytesep);
Antoine Pitrou64672132010-01-13 07:55:48 +00002151 return result;
Christian Heimes44720832008-05-26 13:01:01 +00002152}
2153
2154PyDoc_STRVAR(rsplit__doc__,
2155"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2156\n\
2157Return a list of the sections in B, using sep as the delimiter,\n\
2158starting at the end of B and working to the front.\n\
2159If sep is not given, B is split on ASCII whitespace characters\n\
2160(space, tab, return, newline, formfeed, vertical tab).\n\
2161If maxsplit is given, at most maxsplit splits are done.");
2162
2163static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002164bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002165{
Antoine Pitrou64672132010-01-13 07:55:48 +00002166 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2167 Py_ssize_t maxsplit = -1;
Christian Heimes44720832008-05-26 13:01:01 +00002168 const char *s = PyByteArray_AS_STRING(self), *sub;
Antoine Pitrou64672132010-01-13 07:55:48 +00002169 PyObject *list, *subobj = Py_None;
Christian Heimes44720832008-05-26 13:01:01 +00002170 Py_buffer vsub;
2171
2172 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2173 return NULL;
2174 if (maxsplit < 0)
2175 maxsplit = PY_SSIZE_T_MAX;
2176
2177 if (subobj == Py_None)
Antoine Pitrou64672132010-01-13 07:55:48 +00002178 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes44720832008-05-26 13:01:01 +00002179
2180 if (_getbuffer(subobj, &vsub) < 0)
2181 return NULL;
2182 sub = vsub.buf;
2183 n = vsub.len;
2184
Antoine Pitrou64672132010-01-13 07:55:48 +00002185 list = stringlib_rsplit(
2186 (PyObject*) self, s, len, sub, n, maxsplit
2187 );
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00002188 PyBuffer_Release(&vsub);
Christian Heimes44720832008-05-26 13:01:01 +00002189 return list;
Christian Heimes44720832008-05-26 13:01:01 +00002190}
2191
2192PyDoc_STRVAR(reverse__doc__,
2193"B.reverse() -> None\n\
2194\n\
2195Reverse the order of the values in B in place.");
2196static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002197bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Christian Heimes44720832008-05-26 13:01:01 +00002198{
2199 char swap, *head, *tail;
2200 Py_ssize_t i, j, n = Py_SIZE(self);
2201
2202 j = n / 2;
2203 head = self->ob_bytes;
2204 tail = head + n - 1;
2205 for (i = 0; i < j; i++) {
2206 swap = *head;
2207 *head++ = *tail;
2208 *tail-- = swap;
2209 }
2210
2211 Py_RETURN_NONE;
2212}
2213
2214PyDoc_STRVAR(insert__doc__,
2215"B.insert(index, int) -> None\n\
2216\n\
2217Insert a single item into the bytearray before the given index.");
2218static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002219bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes44720832008-05-26 13:01:01 +00002220{
Georg Brandl3e483f62008-07-16 22:57:41 +00002221 PyObject *value;
2222 int ival;
Christian Heimes44720832008-05-26 13:01:01 +00002223 Py_ssize_t where, n = Py_SIZE(self);
2224
Georg Brandl3e483f62008-07-16 22:57:41 +00002225 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
Christian Heimes44720832008-05-26 13:01:01 +00002226 return NULL;
2227
2228 if (n == PY_SSIZE_T_MAX) {
2229 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002230 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002231 return NULL;
2232 }
Georg Brandl3e483f62008-07-16 22:57:41 +00002233 if (!_getbytevalue(value, &ival))
Christian Heimes44720832008-05-26 13:01:01 +00002234 return NULL;
Christian Heimes44720832008-05-26 13:01:01 +00002235 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2236 return NULL;
2237
2238 if (where < 0) {
2239 where += n;
2240 if (where < 0)
2241 where = 0;
2242 }
2243 if (where > n)
2244 where = n;
2245 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
Georg Brandl3e483f62008-07-16 22:57:41 +00002246 self->ob_bytes[where] = ival;
Christian Heimes44720832008-05-26 13:01:01 +00002247
2248 Py_RETURN_NONE;
2249}
2250
2251PyDoc_STRVAR(append__doc__,
2252"B.append(int) -> None\n\
2253\n\
2254Append a single item to the end of B.");
2255static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002256bytearray_append(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002257{
2258 int value;
2259 Py_ssize_t n = Py_SIZE(self);
2260
2261 if (! _getbytevalue(arg, &value))
2262 return NULL;
2263 if (n == PY_SSIZE_T_MAX) {
2264 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson135a7cf2009-09-06 10:32:21 +00002265 "cannot add more objects to bytearray");
Christian Heimes44720832008-05-26 13:01:01 +00002266 return NULL;
2267 }
2268 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2269 return NULL;
2270
2271 self->ob_bytes[n] = value;
2272
2273 Py_RETURN_NONE;
2274}
2275
2276PyDoc_STRVAR(extend__doc__,
2277"B.extend(iterable int) -> None\n\
2278\n\
2279Append all the elements from the iterator or sequence to the\n\
2280end of B.");
2281static PyObject *
Benjamin Petersond6720012009-04-18 15:31:34 +00002282bytearray_extend(PyByteArrayObject *self, PyObject *arg)
Christian Heimes44720832008-05-26 13:01:01 +00002283{
Benjamin Petersond6720012009-04-18 15:31:34 +00002284 PyObject *it, *item, *bytearray_obj;
Christian Heimes44720832008-05-26 13:01:01 +00002285 Py_ssize_t buf_size = 0, len = 0;
2286 int value;
2287 char *buf;
2288
Benjamin Petersond6720012009-04-18 15:31:34 +00002289 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Christian Heimes44720832008-05-26 13:01:01 +00002290 if (PyObject_CheckBuffer(arg)) {
Benjamin Petersond6720012009-04-18 15:31:34 +00002291 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
Christian Heimes44720832008-05-26 13:01:01 +00002292 return NULL;
2293
2294 Py_RETURN_NONE;
2295 }
2296
2297 it = PyObject_GetIter(arg);
2298 if (it == NULL)
2299 return NULL;
2300
Ezio Melotti24b07bc2011-03-15 18:55:01 +02002301 /* Try to determine the length of the argument. 32 is arbitrary. */
Christian Heimes44720832008-05-26 13:01:01 +00002302 buf_size = _PyObject_LengthHint(arg, 32);
Georg Brandl517cfdc2009-04-05 13:16:35 +00002303 if (buf_size == -1) {
2304 Py_DECREF(it);
2305 return NULL;
2306 }
Christian Heimes44720832008-05-26 13:01:01 +00002307
Benjamin Petersond6720012009-04-18 15:31:34 +00002308 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitroufe941772012-04-01 16:05:46 +02002309 if (bytearray_obj == NULL) {
2310 Py_DECREF(it);
Christian Heimes44720832008-05-26 13:01:01 +00002311 return NULL;
Antoine Pitroufe941772012-04-01 16:05:46 +02002312 }
Benjamin Petersond6720012009-04-18 15:31:34 +00002313 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002314
2315 while ((item = PyIter_Next(it)) != NULL) {
2316 if (! _getbytevalue(item, &value)) {
2317 Py_DECREF(item);
2318 Py_DECREF(it);
Benjamin Petersond6720012009-04-18 15:31:34 +00002319 Py_DECREF(bytearray_obj);
Christian Heimes44720832008-05-26 13:01:01 +00002320 return NULL;
2321 }
2322 buf[len++] = value;
2323 Py_DECREF(item);
2324
2325 if (len >= buf_size) {
2326 buf_size = len + (len >> 1) + 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\
2393Remove the first occurance of a value in B.");
2394static 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}