blob: 14444a2e8e2e3319944b3c4a51beeb310e280ec7 [file] [log] [blame]
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001/* PyByteArray (bytearray) implementation */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
5#include "structmember.h"
6#include "bytes_methods.h"
Ethan Furmanb95b5612015-01-23 20:05:18 -08007#include "bytesobject.h"
Gregory P. Smith8cb65692015-04-25 23:22:26 +00008#include "pystrhex.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00009
Martin v. Löwis7252a6e2014-07-27 16:25:09 +020010/*[clinic input]
11class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
12[clinic start generated code]*/
13/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/
14
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000015char _PyByteArray_empty_string[] = "";
Christian Heimes2c9c7a52008-05-26 13:42:13 +000016
17void
18PyByteArray_Fini(void)
19{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000020}
21
22int
23PyByteArray_Init(void)
24{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000025 return 1;
26}
27
28/* end nullbytes support */
29
30/* Helpers */
31
32static int
33_getbytevalue(PyObject* arg, int *value)
34{
35 long face_value;
36
37 if (PyLong_Check(arg)) {
38 face_value = PyLong_AsLong(arg);
Georg Brandl9a54d7c2008-07-16 23:15:30 +000039 } else {
40 PyObject *index = PyNumber_Index(arg);
41 if (index == NULL) {
42 PyErr_Format(PyExc_TypeError, "an integer is required");
Mark Dickinson10de93a2010-07-09 19:25:48 +000043 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000044 return 0;
45 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +000046 face_value = PyLong_AsLong(index);
47 Py_DECREF(index);
48 }
49
50 if (face_value < 0 || face_value >= 256) {
51 /* this includes the OverflowError in case the long is too large */
52 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Mark Dickinson10de93a2010-07-09 19:25:48 +000053 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000054 return 0;
55 }
56
57 *value = face_value;
58 return 1;
59}
60
61static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +000062bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000063{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000064 void *ptr;
65 if (view == NULL) {
Stefan Krah5178d912015-02-03 16:57:21 +010066 PyErr_SetString(PyExc_BufferError,
67 "bytearray_getbuffer: view==NULL argument is obsolete");
68 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000069 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000070 ptr = (void *) PyByteArray_AS_STRING(obj);
Stefan Krah5178d912015-02-03 16:57:21 +010071 /* cannot fail if view != NULL and readonly == 0 */
72 (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
73 obj->ob_exports++;
74 return 0;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000075}
76
77static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +000078bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000079{
80 obj->ob_exports--;
81}
82
Antoine Pitrou5504e892008-12-06 21:27:53 +000083static int
84_canresize(PyByteArrayObject *self)
85{
86 if (self->ob_exports > 0) {
87 PyErr_SetString(PyExc_BufferError,
88 "Existing exports of data: object cannot be re-sized");
89 return 0;
90 }
91 return 1;
92}
93
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030094#include "clinic/bytearrayobject.c.h"
95
Christian Heimes2c9c7a52008-05-26 13:42:13 +000096/* Direct API functions */
97
98PyObject *
99PyByteArray_FromObject(PyObject *input)
100{
101 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
102 input, NULL);
103}
104
105PyObject *
106PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
107{
108 PyByteArrayObject *new;
109 Py_ssize_t alloc;
110
111 if (size < 0) {
112 PyErr_SetString(PyExc_SystemError,
113 "Negative size passed to PyByteArray_FromStringAndSize");
114 return NULL;
115 }
116
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000117 /* Prevent buffer overflow when setting alloc to size+1. */
118 if (size == PY_SSIZE_T_MAX) {
119 return PyErr_NoMemory();
120 }
121
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000122 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
123 if (new == NULL)
124 return NULL;
125
126 if (size == 0) {
127 new->ob_bytes = NULL;
128 alloc = 0;
129 }
130 else {
131 alloc = size + 1;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100132 new->ob_bytes = PyObject_Malloc(alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000133 if (new->ob_bytes == NULL) {
134 Py_DECREF(new);
135 return PyErr_NoMemory();
136 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +0000137 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000138 memcpy(new->ob_bytes, bytes, size);
139 new->ob_bytes[size] = '\0'; /* Trailing null byte */
140 }
141 Py_SIZE(new) = size;
142 new->ob_alloc = alloc;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200143 new->ob_start = new->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000144 new->ob_exports = 0;
145
146 return (PyObject *)new;
147}
148
149Py_ssize_t
150PyByteArray_Size(PyObject *self)
151{
152 assert(self != NULL);
153 assert(PyByteArray_Check(self));
154
155 return PyByteArray_GET_SIZE(self);
156}
157
158char *
159PyByteArray_AsString(PyObject *self)
160{
161 assert(self != NULL);
162 assert(PyByteArray_Check(self));
163
164 return PyByteArray_AS_STRING(self);
165}
166
167int
Antoine Pitroucc231542014-11-02 18:40:09 +0100168PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000169{
170 void *sval;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200171 PyByteArrayObject *obj = ((PyByteArrayObject *)self);
Antoine Pitroucc231542014-11-02 18:40:09 +0100172 /* All computations are done unsigned to avoid integer overflows
173 (see issue #22335). */
174 size_t alloc = (size_t) obj->ob_alloc;
175 size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
176 size_t size = (size_t) requested_size;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000177
178 assert(self != NULL);
179 assert(PyByteArray_Check(self));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200180 assert(logical_offset <= alloc);
Antoine Pitroucc231542014-11-02 18:40:09 +0100181 assert(requested_size >= 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000182
Antoine Pitroucc231542014-11-02 18:40:09 +0100183 if (requested_size == Py_SIZE(self)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000184 return 0;
185 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200186 if (!_canresize(obj)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000187 return -1;
188 }
189
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200190 if (size + logical_offset + 1 < alloc) {
191 /* Current buffer is large enough to host the requested size,
192 decide on a strategy. */
193 if (size < alloc / 2) {
194 /* Major downsize; resize down to exact size */
195 alloc = size + 1;
196 }
197 else {
198 /* Minor downsize; quick exit */
199 Py_SIZE(self) = size;
200 PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
201 return 0;
202 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000203 }
204 else {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200205 /* Need growing, decide on a strategy */
206 if (size <= alloc * 1.125) {
207 /* Moderate upsize; overallocate similar to list_resize() */
208 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
209 }
210 else {
211 /* Major upsize; resize up to exact size */
212 alloc = size + 1;
213 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000214 }
Antoine Pitroucc231542014-11-02 18:40:09 +0100215 if (alloc > PY_SSIZE_T_MAX) {
216 PyErr_NoMemory();
217 return -1;
218 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000219
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200220 if (logical_offset > 0) {
221 sval = PyObject_Malloc(alloc);
222 if (sval == NULL) {
223 PyErr_NoMemory();
224 return -1;
225 }
Antoine Pitroucc231542014-11-02 18:40:09 +0100226 memcpy(sval, PyByteArray_AS_STRING(self),
227 Py_MIN(requested_size, Py_SIZE(self)));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200228 PyObject_Free(obj->ob_bytes);
229 }
230 else {
231 sval = PyObject_Realloc(obj->ob_bytes, alloc);
232 if (sval == NULL) {
233 PyErr_NoMemory();
234 return -1;
235 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000236 }
237
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200238 obj->ob_bytes = obj->ob_start = sval;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000239 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200240 obj->ob_alloc = alloc;
241 obj->ob_bytes[size] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000242
243 return 0;
244}
245
246PyObject *
247PyByteArray_Concat(PyObject *a, PyObject *b)
248{
249 Py_ssize_t size;
250 Py_buffer va, vb;
251 PyByteArrayObject *result = NULL;
252
253 va.len = -1;
254 vb.len = -1;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200255 if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
256 PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000257 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
258 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
259 goto done;
260 }
261
262 size = va.len + vb.len;
263 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000264 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000265 goto done;
266 }
267
268 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
269 if (result != NULL) {
270 memcpy(result->ob_bytes, va.buf, va.len);
271 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
272 }
273
274 done:
275 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000276 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000277 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000278 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000279 return (PyObject *)result;
280}
281
Ethan Furmanb95b5612015-01-23 20:05:18 -0800282static PyObject *
283bytearray_format(PyByteArrayObject *self, PyObject *args)
284{
285 PyObject *bytes_in, *bytes_out, *res;
286 char *bytestring;
287
288 if (self == NULL || !PyByteArray_Check(self) || args == NULL) {
289 PyErr_BadInternalCall();
290 return NULL;
291 }
292 bytestring = PyByteArray_AS_STRING(self);
293 bytes_in = PyBytes_FromString(bytestring);
294 if (bytes_in == NULL)
295 return NULL;
296 bytes_out = _PyBytes_Format(bytes_in, args);
297 Py_DECREF(bytes_in);
298 if (bytes_out == NULL)
299 return NULL;
300 res = PyByteArray_FromObject(bytes_out);
301 Py_DECREF(bytes_out);
302 if (res == NULL)
303 return NULL;
304 return res;
305}
306
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000307/* Functions stuffed into the type object */
308
309static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000310bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000311{
312 return Py_SIZE(self);
313}
314
315static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000316bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000317{
318 Py_ssize_t mysize;
319 Py_ssize_t size;
320 Py_buffer vo;
321
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200322 if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000323 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
324 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
325 return NULL;
326 }
327
328 mysize = Py_SIZE(self);
329 size = mysize + vo.len;
330 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000331 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000332 return PyErr_NoMemory();
333 }
334 if (size < self->ob_alloc) {
335 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200336 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000337 }
338 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000339 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000340 return NULL;
341 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200342 memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000343 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000344 Py_INCREF(self);
345 return (PyObject *)self;
346}
347
348static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000349bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000350{
351 PyByteArrayObject *result;
352 Py_ssize_t mysize;
353 Py_ssize_t size;
354
355 if (count < 0)
356 count = 0;
357 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000358 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000359 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000360 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000361 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
362 if (result != NULL && size != 0) {
363 if (mysize == 1)
364 memset(result->ob_bytes, self->ob_bytes[0], size);
365 else {
366 Py_ssize_t i;
367 for (i = 0; i < count; i++)
368 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
369 }
370 }
371 return (PyObject *)result;
372}
373
374static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000375bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000376{
377 Py_ssize_t mysize;
378 Py_ssize_t size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200379 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000380
381 if (count < 0)
382 count = 0;
383 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000384 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000385 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000386 size = mysize * count;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200387 if (PyByteArray_Resize((PyObject *)self, size) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000388 return NULL;
389
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200390 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000391 if (mysize == 1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200392 memset(buf, buf[0], size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000393 else {
394 Py_ssize_t i;
395 for (i = 1; i < count; i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200396 memcpy(buf + i*mysize, buf, mysize);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000397 }
398
399 Py_INCREF(self);
400 return (PyObject *)self;
401}
402
403static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000404bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000405{
406 if (i < 0)
407 i += Py_SIZE(self);
408 if (i < 0 || i >= Py_SIZE(self)) {
409 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
410 return NULL;
411 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200412 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000413}
414
415static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000416bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000417{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000418 if (PyIndex_Check(index)) {
419 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000420
421 if (i == -1 && PyErr_Occurred())
422 return NULL;
423
424 if (i < 0)
425 i += PyByteArray_GET_SIZE(self);
426
427 if (i < 0 || i >= Py_SIZE(self)) {
428 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
429 return NULL;
430 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200431 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000432 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000433 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000434 Py_ssize_t start, stop, step, slicelength, cur, i;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000435 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000436 PyByteArray_GET_SIZE(self),
437 &start, &stop, &step, &slicelength) < 0) {
438 return NULL;
439 }
440
441 if (slicelength <= 0)
442 return PyByteArray_FromStringAndSize("", 0);
443 else if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200444 return PyByteArray_FromStringAndSize(
445 PyByteArray_AS_STRING(self) + start, slicelength);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000446 }
447 else {
448 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000449 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000450 PyObject *result;
451
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000452 result = PyByteArray_FromStringAndSize(NULL, slicelength);
453 if (result == NULL)
454 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000455
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000456 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000457 for (cur = start, i = 0; i < slicelength;
458 cur += step, i++) {
459 result_buf[i] = source_buf[cur];
460 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000461 return result;
462 }
463 }
464 else {
Terry Jan Reedyffff1442014-08-02 01:30:37 -0400465 PyErr_Format(PyExc_TypeError,
466 "bytearray indices must be integers or slices, not %.200s",
467 Py_TYPE(index)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000468 return NULL;
469 }
470}
471
472static int
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200473bytearray_setslice_linear(PyByteArrayObject *self,
474 Py_ssize_t lo, Py_ssize_t hi,
475 char *bytes, Py_ssize_t bytes_len)
476{
477 Py_ssize_t avail = hi - lo;
478 char *buf = PyByteArray_AS_STRING(self);
479 Py_ssize_t growth = bytes_len - avail;
Victor Stinner84557232013-11-21 12:29:51 +0100480 int res = 0;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200481 assert(avail >= 0);
482
Victor Stinner84557232013-11-21 12:29:51 +0100483 if (growth < 0) {
484 if (!_canresize(self))
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200485 return -1;
Victor Stinner84557232013-11-21 12:29:51 +0100486
487 if (lo == 0) {
488 /* Shrink the buffer by advancing its logical start */
489 self->ob_start -= growth;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200490 /*
Victor Stinner84557232013-11-21 12:29:51 +0100491 0 lo hi old_size
492 | |<----avail----->|<-----tail------>|
493 | |<-bytes_len->|<-----tail------>|
494 0 new_lo new_hi new_size
495 */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200496 }
Victor Stinner84557232013-11-21 12:29:51 +0100497 else {
498 /*
499 0 lo hi old_size
500 | |<----avail----->|<-----tomove------>|
501 | |<-bytes_len->|<-----tomove------>|
502 0 lo new_hi new_size
503 */
504 memmove(buf + lo + bytes_len, buf + hi,
505 Py_SIZE(self) - hi);
506 }
507 if (PyByteArray_Resize((PyObject *)self,
508 Py_SIZE(self) + growth) < 0) {
509 /* Issue #19578: Handling the memory allocation failure here is
510 tricky here because the bytearray object has already been
511 modified. Depending on growth and lo, the behaviour is
512 different.
513
514 If growth < 0 and lo != 0, the operation is completed, but a
515 MemoryError is still raised and the memory block is not
516 shrinked. Otherwise, the bytearray is restored in its previous
517 state and a MemoryError is raised. */
518 if (lo == 0) {
519 self->ob_start += growth;
520 return -1;
521 }
522 /* memmove() removed bytes, the bytearray object cannot be
523 restored in its previous state. */
524 Py_SIZE(self) += growth;
525 res = -1;
526 }
527 buf = PyByteArray_AS_STRING(self);
528 }
529 else if (growth > 0) {
530 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
531 PyErr_NoMemory();
532 return -1;
533 }
534
535 if (PyByteArray_Resize((PyObject *)self,
536 Py_SIZE(self) + growth) < 0) {
537 return -1;
538 }
539 buf = PyByteArray_AS_STRING(self);
540 /* Make the place for the additional bytes */
541 /*
542 0 lo hi old_size
543 | |<-avail->|<-----tomove------>|
544 | |<---bytes_len-->|<-----tomove------>|
545 0 lo new_hi new_size
546 */
547 memmove(buf + lo + bytes_len, buf + hi,
548 Py_SIZE(self) - lo - bytes_len);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200549 }
550
551 if (bytes_len > 0)
552 memcpy(buf + lo, bytes, bytes_len);
Victor Stinner84557232013-11-21 12:29:51 +0100553 return res;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200554}
555
556static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000557bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000558 PyObject *values)
559{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200560 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000561 void *bytes;
562 Py_buffer vbytes;
563 int res = 0;
564
565 vbytes.len = -1;
566 if (values == (PyObject *)self) {
567 /* Make a copy and call this function recursively */
568 int err;
569 values = PyByteArray_FromObject(values);
570 if (values == NULL)
571 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000572 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000573 Py_DECREF(values);
574 return err;
575 }
576 if (values == NULL) {
577 /* del b[lo:hi] */
578 bytes = NULL;
579 needed = 0;
580 }
581 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200582 if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
583 PyErr_Format(PyExc_TypeError,
584 "can't set bytearray slice from %.100s",
585 Py_TYPE(values)->tp_name);
586 return -1;
587 }
588 needed = vbytes.len;
589 bytes = vbytes.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000590 }
591
592 if (lo < 0)
593 lo = 0;
594 if (hi < lo)
595 hi = lo;
596 if (hi > Py_SIZE(self))
597 hi = Py_SIZE(self);
598
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200599 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000600 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200601 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000602 return res;
603}
604
605static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000606bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000607{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000608 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000609
610 if (i < 0)
611 i += Py_SIZE(self);
612
613 if (i < 0 || i >= Py_SIZE(self)) {
614 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
615 return -1;
616 }
617
618 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000619 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000620
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000621 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000622 return -1;
623
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200624 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000625 return 0;
626}
627
628static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000629bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000630{
631 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200632 char *buf, *bytes;
633 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000634
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000635 if (PyIndex_Check(index)) {
636 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000637
638 if (i == -1 && PyErr_Occurred())
639 return -1;
640
641 if (i < 0)
642 i += PyByteArray_GET_SIZE(self);
643
644 if (i < 0 || i >= Py_SIZE(self)) {
645 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
646 return -1;
647 }
648
649 if (values == NULL) {
650 /* Fall through to slice assignment */
651 start = i;
652 stop = i + 1;
653 step = 1;
654 slicelen = 1;
655 }
656 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000657 int ival;
658 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000659 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200660 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000661 return 0;
662 }
663 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000664 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000665 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000666 PyByteArray_GET_SIZE(self),
667 &start, &stop, &step, &slicelen) < 0) {
668 return -1;
669 }
670 }
671 else {
Terry Jan Reedyffff1442014-08-02 01:30:37 -0400672 PyErr_Format(PyExc_TypeError,
673 "bytearray indices must be integers or slices, not %.200s",
674 Py_TYPE(index)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000675 return -1;
676 }
677
678 if (values == NULL) {
679 bytes = NULL;
680 needed = 0;
681 }
682 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100683 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200684 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
685 PyErr_SetString(PyExc_TypeError,
686 "can assign only bytes, buffers, or iterables "
687 "of ints in range(0, 256)");
688 return -1;
689 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000690 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000691 values = PyByteArray_FromObject(values);
692 if (values == NULL)
693 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000694 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000695 Py_DECREF(values);
696 return err;
697 }
698 else {
699 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200700 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000701 needed = Py_SIZE(values);
702 }
703 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
704 if ((step < 0 && start < stop) ||
705 (step > 0 && start > stop))
706 stop = start;
707 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200708 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000709 }
710 else {
711 if (needed == 0) {
712 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000713 size_t cur;
714 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000715
Antoine Pitrou5504e892008-12-06 21:27:53 +0000716 if (!_canresize(self))
717 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000718
719 if (slicelen == 0)
720 /* Nothing to do here. */
721 return 0;
722
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000723 if (step < 0) {
724 stop = start + 1;
725 start = stop + step * (slicelen - 1) - 1;
726 step = -step;
727 }
728 for (cur = start, i = 0;
729 i < slicelen; cur += step, i++) {
730 Py_ssize_t lim = step - 1;
731
Mark Dickinson66f575b2010-02-14 12:53:32 +0000732 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000733 lim = PyByteArray_GET_SIZE(self) - cur - 1;
734
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200735 memmove(buf + cur - i,
736 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000737 }
738 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000739 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000740 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200741 memmove(buf + cur - slicelen,
742 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000743 PyByteArray_GET_SIZE(self) - cur);
744 }
745 if (PyByteArray_Resize((PyObject *)self,
746 PyByteArray_GET_SIZE(self) - slicelen) < 0)
747 return -1;
748
749 return 0;
750 }
751 else {
752 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000753 Py_ssize_t i;
754 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000755
756 if (needed != slicelen) {
757 PyErr_Format(PyExc_ValueError,
758 "attempt to assign bytes of size %zd "
759 "to extended slice of size %zd",
760 needed, slicelen);
761 return -1;
762 }
763 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200764 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000765 return 0;
766 }
767 }
768}
769
770static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000771bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000772{
773 static char *kwlist[] = {"source", "encoding", "errors", 0};
774 PyObject *arg = NULL;
775 const char *encoding = NULL;
776 const char *errors = NULL;
777 Py_ssize_t count;
778 PyObject *it;
779 PyObject *(*iternext)(PyObject *);
780
781 if (Py_SIZE(self) != 0) {
782 /* Empty previous contents (yes, do this first of all!) */
783 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
784 return -1;
785 }
786
787 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000788 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000789 &arg, &encoding, &errors))
790 return -1;
791
792 /* Make a quick exit if no first argument */
793 if (arg == NULL) {
794 if (encoding != NULL || errors != NULL) {
795 PyErr_SetString(PyExc_TypeError,
796 "encoding or errors without sequence argument");
797 return -1;
798 }
799 return 0;
800 }
801
802 if (PyUnicode_Check(arg)) {
803 /* Encode via the codec registry */
804 PyObject *encoded, *new;
805 if (encoding == NULL) {
806 PyErr_SetString(PyExc_TypeError,
807 "string argument without an encoding");
808 return -1;
809 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000810 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000811 if (encoded == NULL)
812 return -1;
813 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000814 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000815 Py_DECREF(encoded);
816 if (new == NULL)
817 return -1;
818 Py_DECREF(new);
819 return 0;
820 }
821
822 /* If it's not unicode, there can't be encoding or errors */
823 if (encoding != NULL || errors != NULL) {
824 PyErr_SetString(PyExc_TypeError,
825 "encoding or errors without a string argument");
826 return -1;
827 }
828
829 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000830 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
831 if (count == -1 && PyErr_Occurred()) {
832 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000833 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000834 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000835 }
836 else if (count < 0) {
837 PyErr_SetString(PyExc_ValueError, "negative count");
838 return -1;
839 }
840 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000841 if (count > 0) {
Victor Stinner2bc4d952014-06-02 22:22:42 +0200842 if (PyByteArray_Resize((PyObject *)self, count))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000843 return -1;
Victor Stinner2bc4d952014-06-02 22:22:42 +0200844 memset(PyByteArray_AS_STRING(self), 0, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000845 }
846 return 0;
847 }
848
849 /* Use the buffer API */
850 if (PyObject_CheckBuffer(arg)) {
851 Py_ssize_t size;
852 Py_buffer view;
853 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
854 return -1;
855 size = view.len;
856 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200857 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
858 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200859 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000860 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000861 return 0;
862 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000863 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000864 return -1;
865 }
866
867 /* XXX Optimize this if the arguments is a list, tuple */
868
869 /* Get the iterator */
870 it = PyObject_GetIter(arg);
871 if (it == NULL)
872 return -1;
873 iternext = *Py_TYPE(it)->tp_iternext;
874
875 /* Run the iterator to exhaustion */
876 for (;;) {
877 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000878 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000879
880 /* Get the next item */
881 item = iternext(it);
882 if (item == NULL) {
883 if (PyErr_Occurred()) {
884 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
885 goto error;
886 PyErr_Clear();
887 }
888 break;
889 }
890
891 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000892 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000893 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000894 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000895 goto error;
896
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000897 /* Append the byte */
898 if (Py_SIZE(self) < self->ob_alloc)
899 Py_SIZE(self)++;
900 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
901 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200902 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000903 }
904
905 /* Clean up and return success */
906 Py_DECREF(it);
907 return 0;
908
909 error:
910 /* Error handling when it != NULL */
911 Py_DECREF(it);
912 return -1;
913}
914
915/* Mostly copied from string_repr, but without the
916 "smart quote" functionality. */
917static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000918bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000919{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000920 const char *quote_prefix = "bytearray(b";
921 const char *quote_postfix = ")";
922 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200923 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000924 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000925 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200926 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200927 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200928 char c;
929 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200930 int quote;
931 char *test, *start;
932 char *buffer;
933
934 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000935 PyErr_SetString(PyExc_OverflowError,
936 "bytearray object is too large to make repr");
937 return NULL;
938 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200939
940 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100941 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200942 if (buffer == NULL) {
943 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000944 return NULL;
945 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000946
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200947 /* Figure out which quote to use; single is preferred */
948 quote = '\'';
949 start = PyByteArray_AS_STRING(self);
950 for (test = start; test < start+length; ++test) {
951 if (*test == '"') {
952 quote = '\''; /* back to single */
953 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000954 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200955 else if (*test == '\'')
956 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000957 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200958
959 p = buffer;
960 while (*quote_prefix)
961 *p++ = *quote_prefix++;
962 *p++ = quote;
963
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200964 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200965 for (i = 0; i < length; i++) {
966 /* There's at least enough room for a hex escape
967 and a closing quote. */
968 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200969 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200970 if (c == '\'' || c == '\\')
971 *p++ = '\\', *p++ = c;
972 else if (c == '\t')
973 *p++ = '\\', *p++ = 't';
974 else if (c == '\n')
975 *p++ = '\\', *p++ = 'n';
976 else if (c == '\r')
977 *p++ = '\\', *p++ = 'r';
978 else if (c == 0)
979 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
980 else if (c < ' ' || c >= 0x7f) {
981 *p++ = '\\';
982 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200983 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
984 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200985 }
986 else
987 *p++ = c;
988 }
989 assert(newsize - (p - buffer) >= 1);
990 *p++ = quote;
991 while (*quote_postfix) {
992 *p++ = *quote_postfix++;
993 }
994
995 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100996 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200997 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000998}
999
1000static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001001bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001002{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001003 if (Py_BytesWarningFlag) {
1004 if (PyErr_WarnEx(PyExc_BytesWarning,
1005 "str() on a bytearray instance", 1))
1006 return NULL;
1007 }
1008 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001009}
1010
1011static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001012bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001013{
1014 Py_ssize_t self_size, other_size;
1015 Py_buffer self_bytes, other_bytes;
1016 PyObject *res;
1017 Py_ssize_t minsize;
1018 int cmp;
1019
1020 /* Bytes can be compared to anything that supports the (binary)
1021 buffer API. Except that a comparison with Unicode is always an
1022 error, even if the comparison is for equality. */
1023 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1024 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +00001025 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001026 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +00001027 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001028 return NULL;
1029 }
1030
Brian Curtindfc80e32011-08-10 20:28:54 -05001031 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001032 }
1033
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001034 if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001035 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -05001036 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001037 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001038 self_size = self_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001039
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001040 if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001041 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001042 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001043 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001044 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001045 other_size = other_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001046
1047 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1048 /* Shortcut: if the lengths differ, the objects differ */
1049 cmp = (op == Py_NE);
1050 }
1051 else {
1052 minsize = self_size;
1053 if (other_size < minsize)
1054 minsize = other_size;
1055
1056 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1057 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1058
1059 if (cmp == 0) {
1060 if (self_size < other_size)
1061 cmp = -1;
1062 else if (self_size > other_size)
1063 cmp = 1;
1064 }
1065
1066 switch (op) {
1067 case Py_LT: cmp = cmp < 0; break;
1068 case Py_LE: cmp = cmp <= 0; break;
1069 case Py_EQ: cmp = cmp == 0; break;
1070 case Py_NE: cmp = cmp != 0; break;
1071 case Py_GT: cmp = cmp > 0; break;
1072 case Py_GE: cmp = cmp >= 0; break;
1073 }
1074 }
1075
1076 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001077 PyBuffer_Release(&self_bytes);
1078 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001079 Py_INCREF(res);
1080 return res;
1081}
1082
1083static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001084bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001085{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001086 if (self->ob_exports > 0) {
1087 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001088 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001089 PyErr_Print();
1090 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001091 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001092 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001093 }
1094 Py_TYPE(self)->tp_free((PyObject *)self);
1095}
1096
1097
1098/* -------------------------------------------------------------------- */
1099/* Methods */
1100
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001101#define FASTSEARCH fastsearch
1102#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001103#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001104#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001105#define STRINGLIB_LEN PyByteArray_GET_SIZE
1106#define STRINGLIB_STR PyByteArray_AS_STRING
1107#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001108#define STRINGLIB_ISSPACE Py_ISSPACE
1109#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001110#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1111#define STRINGLIB_MUTABLE 1
1112
1113#include "stringlib/fastsearch.h"
1114#include "stringlib/count.h"
1115#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001116#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001117#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001118#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001119#include "stringlib/ctype.h"
1120#include "stringlib/transmogrify.h"
1121
1122
1123/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1124were copied from the old char* style string object. */
1125
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001126/* helper macro to fixup start/end slice values */
1127#define ADJUST_INDICES(start, end, len) \
1128 if (end > len) \
1129 end = len; \
1130 else if (end < 0) { \
1131 end += len; \
1132 if (end < 0) \
1133 end = 0; \
1134 } \
1135 if (start < 0) { \
1136 start += len; \
1137 if (start < 0) \
1138 start = 0; \
1139 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001140
1141Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001142bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001143{
1144 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001145 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001146 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001147 const char *sub;
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001148 Py_ssize_t len, sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001149 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1150 Py_ssize_t res;
1151
Antoine Pitrouac65d962011-10-20 23:54:17 +02001152 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1153 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001154 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001155
1156 if (subobj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001157 if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001158 return -2;
1159
1160 sub = subbuf.buf;
1161 sub_len = subbuf.len;
1162 }
1163 else {
1164 sub = &byte;
1165 sub_len = 1;
1166 }
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001167 len = PyByteArray_GET_SIZE(self);
Antoine Pitrouac65d962011-10-20 23:54:17 +02001168
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001169 ADJUST_INDICES(start, end, len);
1170 if (end - start < sub_len)
1171 res = -1;
Victor Stinnerdabbfe72015-03-25 03:16:32 +01001172 /* Issue #23573: FIXME, windows has no memrchr() */
1173 else if (sub_len == 1 && dir > 0) {
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001174 unsigned char needle = *sub;
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001175 res = stringlib_fastsearch_memchr_1char(
1176 PyByteArray_AS_STRING(self) + start, end - start,
Christian Heimes4e259132015-04-18 05:54:02 +02001177 needle, needle, FAST_SEARCH);
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001178 if (res >= 0)
1179 res += start;
1180 }
1181 else {
1182 if (dir > 0)
1183 res = stringlib_find_slice(
1184 PyByteArray_AS_STRING(self), len,
1185 sub, sub_len, start, end);
1186 else
1187 res = stringlib_rfind_slice(
1188 PyByteArray_AS_STRING(self), len,
1189 sub, sub_len, start, end);
1190 }
Antoine Pitrouac65d962011-10-20 23:54:17 +02001191
1192 if (subobj)
1193 PyBuffer_Release(&subbuf);
1194
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001195 return res;
1196}
1197
1198PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001199"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001200\n\
1201Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001202such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001203arguments start and end are interpreted as in slice notation.\n\
1204\n\
1205Return -1 on failure.");
1206
1207static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001208bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001209{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001210 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001211 if (result == -2)
1212 return NULL;
1213 return PyLong_FromSsize_t(result);
1214}
1215
1216PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001217"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001218\n\
1219Return the number of non-overlapping occurrences of subsection sub in\n\
1220bytes B[start:end]. Optional arguments start and end are interpreted\n\
1221as in slice notation.");
1222
1223static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001224bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001225{
1226 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001227 const char *str = PyByteArray_AS_STRING(self), *sub;
1228 Py_ssize_t sub_len;
1229 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001230 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001231
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001232 Py_buffer vsub;
1233 PyObject *count_obj;
1234
Antoine Pitrouac65d962011-10-20 23:54:17 +02001235 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1236 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001237 return NULL;
1238
Antoine Pitrouac65d962011-10-20 23:54:17 +02001239 if (sub_obj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001240 if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001241 return NULL;
1242
1243 sub = vsub.buf;
1244 sub_len = vsub.len;
1245 }
1246 else {
1247 sub = &byte;
1248 sub_len = 1;
1249 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001250
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001251 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001252
1253 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001254 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001255 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001256
1257 if (sub_obj)
1258 PyBuffer_Release(&vsub);
1259
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001260 return count_obj;
1261}
1262
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001263/*[clinic input]
1264bytearray.clear
1265
1266 self: self(type="PyByteArrayObject *")
1267
1268Remove all items from the bytearray.
1269[clinic start generated code]*/
1270
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001271static PyObject *
1272bytearray_clear_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001273/*[clinic end generated code: output=85c2fe6aede0956c input=e524fd330abcdc18]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001274{
1275 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1276 return NULL;
1277 Py_RETURN_NONE;
1278}
1279
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001280/*[clinic input]
1281bytearray.copy
1282
1283 self: self(type="PyByteArrayObject *")
1284
1285Return a copy of B.
1286[clinic start generated code]*/
1287
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001288static PyObject *
1289bytearray_copy_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001290/*[clinic end generated code: output=68cfbcfed484c132 input=6d5d2975aa0f33f3]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001291{
1292 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1293 PyByteArray_GET_SIZE(self));
1294}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001295
1296PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001297"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001298\n\
1299Like B.find() but raise ValueError when the subsection is not found.");
1300
1301static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001302bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001303{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001304 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001305 if (result == -2)
1306 return NULL;
1307 if (result == -1) {
1308 PyErr_SetString(PyExc_ValueError,
1309 "subsection not found");
1310 return NULL;
1311 }
1312 return PyLong_FromSsize_t(result);
1313}
1314
1315
1316PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001317"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001318\n\
1319Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001320such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001321arguments start and end are interpreted as in slice notation.\n\
1322\n\
1323Return -1 on failure.");
1324
1325static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001326bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001327{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001328 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001329 if (result == -2)
1330 return NULL;
1331 return PyLong_FromSsize_t(result);
1332}
1333
1334
1335PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001336"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001337\n\
1338Like B.rfind() but raise ValueError when the subsection is not found.");
1339
1340static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001341bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001342{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001343 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001344 if (result == -2)
1345 return NULL;
1346 if (result == -1) {
1347 PyErr_SetString(PyExc_ValueError,
1348 "subsection not found");
1349 return NULL;
1350 }
1351 return PyLong_FromSsize_t(result);
1352}
1353
1354
1355static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001356bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001357{
1358 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1359 if (ival == -1 && PyErr_Occurred()) {
1360 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001361 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001362 PyErr_Clear();
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001363 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001364 return -1;
1365 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1366 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001367 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001368 return pos >= 0;
1369 }
1370 if (ival < 0 || ival >= 256) {
1371 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1372 return -1;
1373 }
1374
Antoine Pitrou0010d372010-08-15 17:12:55 +00001375 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001376}
1377
1378
1379/* Matches the end (direction >= 0) or start (direction < 0) of self
1380 * against substr, using the start and end arguments. Returns
1381 * -1 on error, 0 if not found and 1 if found.
1382 */
1383Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001384_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001385 Py_ssize_t end, int direction)
1386{
1387 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1388 const char* str;
1389 Py_buffer vsubstr;
1390 int rv = 0;
1391
1392 str = PyByteArray_AS_STRING(self);
1393
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001394 if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001395 return -1;
1396
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001397 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001398
1399 if (direction < 0) {
1400 /* startswith */
1401 if (start+vsubstr.len > len) {
1402 goto done;
1403 }
1404 } else {
1405 /* endswith */
1406 if (end-start < vsubstr.len || start > len) {
1407 goto done;
1408 }
1409
1410 if (end-vsubstr.len > start)
1411 start = end - vsubstr.len;
1412 }
1413 if (end-start >= vsubstr.len)
1414 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1415
1416done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001417 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001418 return rv;
1419}
1420
1421
1422PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001423"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001424\n\
1425Return True if B starts with the specified prefix, False otherwise.\n\
1426With optional start, test B beginning at that position.\n\
1427With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001428prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001429
1430static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001431bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001432{
1433 Py_ssize_t start = 0;
1434 Py_ssize_t end = PY_SSIZE_T_MAX;
1435 PyObject *subobj;
1436 int result;
1437
Jesus Ceaac451502011-04-20 17:09:23 +02001438 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001439 return NULL;
1440 if (PyTuple_Check(subobj)) {
1441 Py_ssize_t i;
1442 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001443 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001444 PyTuple_GET_ITEM(subobj, i),
1445 start, end, -1);
1446 if (result == -1)
1447 return NULL;
1448 else if (result) {
1449 Py_RETURN_TRUE;
1450 }
1451 }
1452 Py_RETURN_FALSE;
1453 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001454 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001455 if (result == -1) {
1456 if (PyErr_ExceptionMatches(PyExc_TypeError))
1457 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1458 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001459 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001460 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001461 else
1462 return PyBool_FromLong(result);
1463}
1464
1465PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001466"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001467\n\
1468Return True if B ends with the specified suffix, False otherwise.\n\
1469With optional start, test B beginning at that position.\n\
1470With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001471suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001472
1473static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001474bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001475{
1476 Py_ssize_t start = 0;
1477 Py_ssize_t end = PY_SSIZE_T_MAX;
1478 PyObject *subobj;
1479 int result;
1480
Jesus Ceaac451502011-04-20 17:09:23 +02001481 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001482 return NULL;
1483 if (PyTuple_Check(subobj)) {
1484 Py_ssize_t i;
1485 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001486 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001487 PyTuple_GET_ITEM(subobj, i),
1488 start, end, +1);
1489 if (result == -1)
1490 return NULL;
1491 else if (result) {
1492 Py_RETURN_TRUE;
1493 }
1494 }
1495 Py_RETURN_FALSE;
1496 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001497 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001498 if (result == -1) {
1499 if (PyErr_ExceptionMatches(PyExc_TypeError))
1500 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1501 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001502 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001503 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001504 else
1505 return PyBool_FromLong(result);
1506}
1507
1508
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001509/*[clinic input]
1510bytearray.translate
1511
1512 self: self(type="PyByteArrayObject *")
1513 table: object
1514 Translation table, which must be a bytes object of length 256.
1515 [
1516 deletechars: object
1517 ]
1518 /
1519
1520Return a copy with each character mapped by the given translation table.
1521
1522All characters occurring in the optional argument deletechars are removed.
1523The remaining characters are mapped through the given translation table.
1524[clinic start generated code]*/
1525
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001526static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001527bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
1528 int group_right_1, PyObject *deletechars)
1529/*[clinic end generated code: output=2bebc86a9a1ff083 input=b749ad85f4860824]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001530{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001531 char *input, *output;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001532 const char *table_chars;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001533 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001534 PyObject *input_obj = (PyObject*)self;
1535 const char *output_start;
1536 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001537 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001538 int trans_table[256];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001539 Py_buffer vtable, vdel;
1540
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001541 if (table == Py_None) {
1542 table_chars = NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001543 table = NULL;
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001544 } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001545 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001546 } else {
1547 if (vtable.len != 256) {
1548 PyErr_SetString(PyExc_ValueError,
1549 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001550 PyBuffer_Release(&vtable);
1551 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001552 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001553 table_chars = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001554 }
1555
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001556 if (deletechars != NULL) {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001557 if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001558 if (table != NULL)
Georg Brandl953152f2009-07-22 12:03:59 +00001559 PyBuffer_Release(&vtable);
1560 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001561 }
1562 }
1563 else {
1564 vdel.buf = NULL;
1565 vdel.len = 0;
1566 }
1567
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001568 inlen = PyByteArray_GET_SIZE(input_obj);
1569 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1570 if (result == NULL)
1571 goto done;
1572 output_start = output = PyByteArray_AsString(result);
1573 input = PyByteArray_AS_STRING(input_obj);
1574
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001575 if (vdel.len == 0 && table_chars != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001576 /* If no deletions are required, use faster code */
1577 for (i = inlen; --i >= 0; ) {
1578 c = Py_CHARMASK(*input++);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001579 *output++ = table_chars[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001580 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001581 goto done;
1582 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001583
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001584 if (table_chars == NULL) {
Georg Brandlccc47b62008-12-28 11:44:14 +00001585 for (i = 0; i < 256; i++)
1586 trans_table[i] = Py_CHARMASK(i);
1587 } else {
1588 for (i = 0; i < 256; i++)
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001589 trans_table[i] = Py_CHARMASK(table_chars[i]);
Georg Brandlccc47b62008-12-28 11:44:14 +00001590 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001591
1592 for (i = 0; i < vdel.len; i++)
1593 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1594
1595 for (i = inlen; --i >= 0; ) {
1596 c = Py_CHARMASK(*input++);
1597 if (trans_table[c] != -1)
1598 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1599 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001600 }
1601 /* Fix the size of the resulting string */
1602 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001603 if (PyByteArray_Resize(result, output - output_start) < 0) {
1604 Py_CLEAR(result);
1605 goto done;
1606 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001607
1608done:
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001609 if (table != NULL)
Georg Brandlccc47b62008-12-28 11:44:14 +00001610 PyBuffer_Release(&vtable);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001611 if (deletechars != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001612 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001613 return result;
1614}
1615
1616
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001617/*[clinic input]
1618
1619@staticmethod
1620bytearray.maketrans
1621
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001622 frm: Py_buffer
1623 to: Py_buffer
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001624 /
1625
1626Return a translation table useable for the bytes or bytearray translate method.
1627
1628The returned table will be one where each byte in frm is mapped to the byte at
1629the same position in to.
1630
1631The bytes objects frm and to must be of the same length.
1632[clinic start generated code]*/
1633
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001634static PyObject *
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001635bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001636/*[clinic end generated code: output=1df267d99f56b15e input=5925a81d2fbbf151]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001637{
1638 return _Py_bytes_maketrans(frm, to);
Georg Brandlabc38772009-04-12 15:51:51 +00001639}
1640
1641
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001642/* find and count characters and substrings */
1643
1644#define findchar(target, target_len, c) \
1645 ((char *)memchr((const void *)(target), c, target_len))
1646
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001647
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001648/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001649Py_LOCAL(PyByteArrayObject *)
1650return_self(PyByteArrayObject *self)
1651{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001652 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001653 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1654 PyByteArray_AS_STRING(self),
1655 PyByteArray_GET_SIZE(self));
1656}
1657
1658Py_LOCAL_INLINE(Py_ssize_t)
1659countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1660{
1661 Py_ssize_t count=0;
1662 const char *start=target;
1663 const char *end=target+target_len;
1664
1665 while ( (start=findchar(start, end-start, c)) != NULL ) {
1666 count++;
1667 if (count >= maxcount)
1668 break;
1669 start += 1;
1670 }
1671 return count;
1672}
1673
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001674
1675/* Algorithms for different cases of string replacement */
1676
1677/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1678Py_LOCAL(PyByteArrayObject *)
1679replace_interleave(PyByteArrayObject *self,
1680 const char *to_s, Py_ssize_t to_len,
1681 Py_ssize_t maxcount)
1682{
1683 char *self_s, *result_s;
1684 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001685 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001686 PyByteArrayObject *result;
1687
1688 self_len = PyByteArray_GET_SIZE(self);
1689
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001690 /* 1 at the end plus 1 after every character;
1691 count = min(maxcount, self_len + 1) */
1692 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001693 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001694 else
1695 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1696 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001697
1698 /* Check for overflow */
1699 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001700 assert(count > 0);
1701 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001702 PyErr_SetString(PyExc_OverflowError,
1703 "replace string is too long");
1704 return NULL;
1705 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001706 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001707
1708 if (! (result = (PyByteArrayObject *)
1709 PyByteArray_FromStringAndSize(NULL, result_len)) )
1710 return NULL;
1711
1712 self_s = PyByteArray_AS_STRING(self);
1713 result_s = PyByteArray_AS_STRING(result);
1714
1715 /* TODO: special case single character, which doesn't need memcpy */
1716
1717 /* Lay the first one down (guaranteed this will occur) */
1718 Py_MEMCPY(result_s, to_s, to_len);
1719 result_s += to_len;
1720 count -= 1;
1721
1722 for (i=0; i<count; i++) {
1723 *result_s++ = *self_s++;
1724 Py_MEMCPY(result_s, to_s, to_len);
1725 result_s += to_len;
1726 }
1727
1728 /* Copy the rest of the original string */
1729 Py_MEMCPY(result_s, self_s, self_len-i);
1730
1731 return result;
1732}
1733
1734/* Special case for deleting a single character */
1735/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1736Py_LOCAL(PyByteArrayObject *)
1737replace_delete_single_character(PyByteArrayObject *self,
1738 char from_c, Py_ssize_t maxcount)
1739{
1740 char *self_s, *result_s;
1741 char *start, *next, *end;
1742 Py_ssize_t self_len, result_len;
1743 Py_ssize_t count;
1744 PyByteArrayObject *result;
1745
1746 self_len = PyByteArray_GET_SIZE(self);
1747 self_s = PyByteArray_AS_STRING(self);
1748
1749 count = countchar(self_s, self_len, from_c, maxcount);
1750 if (count == 0) {
1751 return return_self(self);
1752 }
1753
1754 result_len = self_len - count; /* from_len == 1 */
1755 assert(result_len>=0);
1756
1757 if ( (result = (PyByteArrayObject *)
1758 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1759 return NULL;
1760 result_s = PyByteArray_AS_STRING(result);
1761
1762 start = self_s;
1763 end = self_s + self_len;
1764 while (count-- > 0) {
1765 next = findchar(start, end-start, from_c);
1766 if (next == NULL)
1767 break;
1768 Py_MEMCPY(result_s, start, next-start);
1769 result_s += (next-start);
1770 start = next+1;
1771 }
1772 Py_MEMCPY(result_s, start, end-start);
1773
1774 return result;
1775}
1776
1777/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1778
1779Py_LOCAL(PyByteArrayObject *)
1780replace_delete_substring(PyByteArrayObject *self,
1781 const char *from_s, Py_ssize_t from_len,
1782 Py_ssize_t maxcount)
1783{
1784 char *self_s, *result_s;
1785 char *start, *next, *end;
1786 Py_ssize_t self_len, result_len;
1787 Py_ssize_t count, offset;
1788 PyByteArrayObject *result;
1789
1790 self_len = PyByteArray_GET_SIZE(self);
1791 self_s = PyByteArray_AS_STRING(self);
1792
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001793 count = stringlib_count(self_s, self_len,
1794 from_s, from_len,
1795 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001796
1797 if (count == 0) {
1798 /* no matches */
1799 return return_self(self);
1800 }
1801
1802 result_len = self_len - (count * from_len);
1803 assert (result_len>=0);
1804
1805 if ( (result = (PyByteArrayObject *)
1806 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1807 return NULL;
1808
1809 result_s = PyByteArray_AS_STRING(result);
1810
1811 start = self_s;
1812 end = self_s + self_len;
1813 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001814 offset = stringlib_find(start, end-start,
1815 from_s, from_len,
1816 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001817 if (offset == -1)
1818 break;
1819 next = start + offset;
1820
1821 Py_MEMCPY(result_s, start, next-start);
1822
1823 result_s += (next-start);
1824 start = next+from_len;
1825 }
1826 Py_MEMCPY(result_s, start, end-start);
1827 return result;
1828}
1829
1830/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1831Py_LOCAL(PyByteArrayObject *)
1832replace_single_character_in_place(PyByteArrayObject *self,
1833 char from_c, char to_c,
1834 Py_ssize_t maxcount)
1835{
Antoine Pitroud1188562010-06-09 16:38:55 +00001836 char *self_s, *result_s, *start, *end, *next;
1837 Py_ssize_t self_len;
1838 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001839
Antoine Pitroud1188562010-06-09 16:38:55 +00001840 /* The result string will be the same size */
1841 self_s = PyByteArray_AS_STRING(self);
1842 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001843
Antoine Pitroud1188562010-06-09 16:38:55 +00001844 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001845
Antoine Pitroud1188562010-06-09 16:38:55 +00001846 if (next == NULL) {
1847 /* No matches; return the original bytes */
1848 return return_self(self);
1849 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001850
Antoine Pitroud1188562010-06-09 16:38:55 +00001851 /* Need to make a new bytes */
1852 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1853 if (result == NULL)
1854 return NULL;
1855 result_s = PyByteArray_AS_STRING(result);
1856 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001857
Antoine Pitroud1188562010-06-09 16:38:55 +00001858 /* change everything in-place, starting with this one */
1859 start = result_s + (next-self_s);
1860 *start = to_c;
1861 start++;
1862 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001863
Antoine Pitroud1188562010-06-09 16:38:55 +00001864 while (--maxcount > 0) {
1865 next = findchar(start, end-start, from_c);
1866 if (next == NULL)
1867 break;
1868 *next = to_c;
1869 start = next+1;
1870 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001871
Antoine Pitroud1188562010-06-09 16:38:55 +00001872 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001873}
1874
1875/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1876Py_LOCAL(PyByteArrayObject *)
1877replace_substring_in_place(PyByteArrayObject *self,
1878 const char *from_s, Py_ssize_t from_len,
1879 const char *to_s, Py_ssize_t to_len,
1880 Py_ssize_t maxcount)
1881{
1882 char *result_s, *start, *end;
1883 char *self_s;
1884 Py_ssize_t self_len, offset;
1885 PyByteArrayObject *result;
1886
1887 /* The result bytes will be the same size */
1888
1889 self_s = PyByteArray_AS_STRING(self);
1890 self_len = PyByteArray_GET_SIZE(self);
1891
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001892 offset = stringlib_find(self_s, self_len,
1893 from_s, from_len,
1894 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001895 if (offset == -1) {
1896 /* No matches; return the original bytes */
1897 return return_self(self);
1898 }
1899
1900 /* Need to make a new bytes */
1901 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1902 if (result == NULL)
1903 return NULL;
1904 result_s = PyByteArray_AS_STRING(result);
1905 Py_MEMCPY(result_s, self_s, self_len);
1906
1907 /* change everything in-place, starting with this one */
1908 start = result_s + offset;
1909 Py_MEMCPY(start, to_s, from_len);
1910 start += from_len;
1911 end = result_s + self_len;
1912
1913 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001914 offset = stringlib_find(start, end-start,
1915 from_s, from_len,
1916 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001917 if (offset==-1)
1918 break;
1919 Py_MEMCPY(start+offset, to_s, from_len);
1920 start += offset+from_len;
1921 }
1922
1923 return result;
1924}
1925
1926/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1927Py_LOCAL(PyByteArrayObject *)
1928replace_single_character(PyByteArrayObject *self,
1929 char from_c,
1930 const char *to_s, Py_ssize_t to_len,
1931 Py_ssize_t maxcount)
1932{
1933 char *self_s, *result_s;
1934 char *start, *next, *end;
1935 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001936 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001937 PyByteArrayObject *result;
1938
1939 self_s = PyByteArray_AS_STRING(self);
1940 self_len = PyByteArray_GET_SIZE(self);
1941
1942 count = countchar(self_s, self_len, from_c, maxcount);
1943 if (count == 0) {
1944 /* no matches, return unchanged */
1945 return return_self(self);
1946 }
1947
1948 /* use the difference between current and new, hence the "-1" */
1949 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001950 assert(count > 0);
1951 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001952 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1953 return NULL;
1954 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001955 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001956
1957 if ( (result = (PyByteArrayObject *)
1958 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1959 return NULL;
1960 result_s = PyByteArray_AS_STRING(result);
1961
1962 start = self_s;
1963 end = self_s + self_len;
1964 while (count-- > 0) {
1965 next = findchar(start, end-start, from_c);
1966 if (next == NULL)
1967 break;
1968
1969 if (next == start) {
1970 /* replace with the 'to' */
1971 Py_MEMCPY(result_s, to_s, to_len);
1972 result_s += to_len;
1973 start += 1;
1974 } else {
1975 /* copy the unchanged old then the 'to' */
1976 Py_MEMCPY(result_s, start, next-start);
1977 result_s += (next-start);
1978 Py_MEMCPY(result_s, to_s, to_len);
1979 result_s += to_len;
1980 start = next+1;
1981 }
1982 }
1983 /* Copy the remainder of the remaining bytes */
1984 Py_MEMCPY(result_s, start, end-start);
1985
1986 return result;
1987}
1988
1989/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1990Py_LOCAL(PyByteArrayObject *)
1991replace_substring(PyByteArrayObject *self,
1992 const char *from_s, Py_ssize_t from_len,
1993 const char *to_s, Py_ssize_t to_len,
1994 Py_ssize_t maxcount)
1995{
1996 char *self_s, *result_s;
1997 char *start, *next, *end;
1998 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001999 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002000 PyByteArrayObject *result;
2001
2002 self_s = PyByteArray_AS_STRING(self);
2003 self_len = PyByteArray_GET_SIZE(self);
2004
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002005 count = stringlib_count(self_s, self_len,
2006 from_s, from_len,
2007 maxcount);
2008
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002009 if (count == 0) {
2010 /* no matches, return unchanged */
2011 return return_self(self);
2012 }
2013
2014 /* Check for overflow */
2015 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002016 assert(count > 0);
2017 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002018 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
2019 return NULL;
2020 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002021 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002022
2023 if ( (result = (PyByteArrayObject *)
2024 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
2025 return NULL;
2026 result_s = PyByteArray_AS_STRING(result);
2027
2028 start = self_s;
2029 end = self_s + self_len;
2030 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002031 offset = stringlib_find(start, end-start,
2032 from_s, from_len,
2033 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002034 if (offset == -1)
2035 break;
2036 next = start+offset;
2037 if (next == start) {
2038 /* replace with the 'to' */
2039 Py_MEMCPY(result_s, to_s, to_len);
2040 result_s += to_len;
2041 start += from_len;
2042 } else {
2043 /* copy the unchanged old then the 'to' */
2044 Py_MEMCPY(result_s, start, next-start);
2045 result_s += (next-start);
2046 Py_MEMCPY(result_s, to_s, to_len);
2047 result_s += to_len;
2048 start = next+from_len;
2049 }
2050 }
2051 /* Copy the remainder of the remaining bytes */
2052 Py_MEMCPY(result_s, start, end-start);
2053
2054 return result;
2055}
2056
2057
2058Py_LOCAL(PyByteArrayObject *)
2059replace(PyByteArrayObject *self,
2060 const char *from_s, Py_ssize_t from_len,
2061 const char *to_s, Py_ssize_t to_len,
2062 Py_ssize_t maxcount)
2063{
2064 if (maxcount < 0) {
2065 maxcount = PY_SSIZE_T_MAX;
2066 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
2067 /* nothing to do; return the original bytes */
2068 return return_self(self);
2069 }
2070
2071 if (maxcount == 0 ||
2072 (from_len == 0 && to_len == 0)) {
2073 /* nothing to do; return the original bytes */
2074 return return_self(self);
2075 }
2076
2077 /* Handle zero-length special cases */
2078
2079 if (from_len == 0) {
2080 /* insert the 'to' bytes everywhere. */
2081 /* >>> "Python".replace("", ".") */
2082 /* '.P.y.t.h.o.n.' */
2083 return replace_interleave(self, to_s, to_len, maxcount);
2084 }
2085
2086 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2087 /* point for an empty self bytes to generate a non-empty bytes */
2088 /* Special case so the remaining code always gets a non-empty bytes */
2089 if (PyByteArray_GET_SIZE(self) == 0) {
2090 return return_self(self);
2091 }
2092
2093 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002094 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002095 if (from_len == 1) {
2096 return replace_delete_single_character(
2097 self, from_s[0], maxcount);
2098 } else {
2099 return replace_delete_substring(self, from_s, from_len, maxcount);
2100 }
2101 }
2102
2103 /* Handle special case where both bytes have the same length */
2104
2105 if (from_len == to_len) {
2106 if (from_len == 1) {
2107 return replace_single_character_in_place(
2108 self,
2109 from_s[0],
2110 to_s[0],
2111 maxcount);
2112 } else {
2113 return replace_substring_in_place(
2114 self, from_s, from_len, to_s, to_len, maxcount);
2115 }
2116 }
2117
2118 /* Otherwise use the more generic algorithms */
2119 if (from_len == 1) {
2120 return replace_single_character(self, from_s[0],
2121 to_s, to_len, maxcount);
2122 } else {
2123 /* len('from')>=2, len('to')>=1 */
2124 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2125 }
2126}
2127
2128
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002129/*[clinic input]
2130bytearray.replace
2131
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002132 old: Py_buffer
2133 new: Py_buffer
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002134 count: Py_ssize_t = -1
2135 Maximum number of occurrences to replace.
2136 -1 (the default value) means replace all occurrences.
2137 /
2138
2139Return a copy with all occurrences of substring old replaced by new.
2140
2141If the optional argument count is given, only the first count occurrences are
2142replaced.
2143[clinic start generated code]*/
2144
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002145static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002146bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old,
2147 Py_buffer *new, Py_ssize_t count)
2148/*[clinic end generated code: output=d39884c4dc59412a input=aa379d988637c7fb]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002149{
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002150 return (PyObject *)replace((PyByteArrayObject *) self,
2151 old->buf, old->len,
2152 new->buf, new->len, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002153}
2154
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002155/*[clinic input]
2156bytearray.split
2157
2158 sep: object = None
2159 The delimiter according which to split the bytearray.
2160 None (the default value) means split on ASCII whitespace characters
2161 (space, tab, return, newline, formfeed, vertical tab).
2162 maxsplit: Py_ssize_t = -1
2163 Maximum number of splits to do.
2164 -1 (the default value) means no limit.
2165
2166Return a list of the sections in the bytearray, using sep as the delimiter.
2167[clinic start generated code]*/
2168
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002169static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002170bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
2171 Py_ssize_t maxsplit)
2172/*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002173{
2174 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002175 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002176 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002177 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002178
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002179 if (maxsplit < 0)
2180 maxsplit = PY_SSIZE_T_MAX;
2181
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002182 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002183 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002184
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002185 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002186 return NULL;
2187 sub = vsub.buf;
2188 n = vsub.len;
2189
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002190 list = stringlib_split(
2191 (PyObject*) self, s, len, sub, n, maxsplit
2192 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002193 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002194 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002195}
2196
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002197/*[clinic input]
2198bytearray.partition
2199
2200 self: self(type="PyByteArrayObject *")
2201 sep: object
2202 /
2203
2204Partition the bytearray into three parts using the given separator.
2205
2206This will search for the separator sep in the bytearray. If the separator is
2207found, returns a 3-tuple containing the part before the separator, the
2208separator itself, and the part after it.
2209
2210If the separator is not found, returns a 3-tuple containing the original
2211bytearray object and two empty bytearray objects.
2212[clinic start generated code]*/
2213
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002214static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002215bytearray_partition(PyByteArrayObject *self, PyObject *sep)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002216/*[clinic end generated code: output=45d2525ddd35f957 input=7d7fe37b1696d506]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002217{
2218 PyObject *bytesep, *result;
2219
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002220 bytesep = PyByteArray_FromObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002221 if (! bytesep)
2222 return NULL;
2223
2224 result = stringlib_partition(
2225 (PyObject*) self,
2226 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2227 bytesep,
2228 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2229 );
2230
2231 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002232 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002233}
2234
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002235/*[clinic input]
2236bytearray.rpartition
2237
2238 self: self(type="PyByteArrayObject *")
2239 sep: object
2240 /
2241
2242Partition the bytes into three parts using the given separator.
2243
2244This will search for the separator sep in the bytearray, starting and the end.
2245If the separator is found, returns a 3-tuple containing the part before the
2246separator, the separator itself, and the part after it.
2247
2248If the separator is not found, returns a 3-tuple containing two empty bytearray
2249objects and the original bytearray object.
2250[clinic start generated code]*/
2251
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002252static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002253bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002254/*[clinic end generated code: output=440de3c9426115e8 input=9b8cd540c1b75853]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002255{
2256 PyObject *bytesep, *result;
2257
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002258 bytesep = PyByteArray_FromObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002259 if (! bytesep)
2260 return NULL;
2261
2262 result = stringlib_rpartition(
2263 (PyObject*) self,
2264 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2265 bytesep,
2266 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2267 );
2268
2269 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002270 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002271}
2272
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002273/*[clinic input]
2274bytearray.rsplit = bytearray.split
2275
2276Return a list of the sections in the bytearray, using sep as the delimiter.
2277
2278Splitting is done starting at the end of the bytearray and working to the front.
2279[clinic start generated code]*/
2280
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002281static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002282bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
2283 Py_ssize_t maxsplit)
2284/*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002285{
2286 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002287 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002288 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002289 Py_buffer vsub;
2290
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002291 if (maxsplit < 0)
2292 maxsplit = PY_SSIZE_T_MAX;
2293
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002294 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002295 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002296
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002297 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002298 return NULL;
2299 sub = vsub.buf;
2300 n = vsub.len;
2301
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002302 list = stringlib_rsplit(
2303 (PyObject*) self, s, len, sub, n, maxsplit
2304 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002305 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002306 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002307}
2308
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002309/*[clinic input]
2310bytearray.reverse
2311
2312 self: self(type="PyByteArrayObject *")
2313
2314Reverse the order of the values in B in place.
2315[clinic start generated code]*/
2316
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002317static PyObject *
2318bytearray_reverse_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002319/*[clinic end generated code: output=9f7616f29ab309d3 input=7933a499b8597bd1]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002320{
2321 char swap, *head, *tail;
2322 Py_ssize_t i, j, n = Py_SIZE(self);
2323
2324 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002325 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002326 tail = head + n - 1;
2327 for (i = 0; i < j; i++) {
2328 swap = *head;
2329 *head++ = *tail;
2330 *tail-- = swap;
2331 }
2332
2333 Py_RETURN_NONE;
2334}
2335
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002336
2337/*[python input]
2338class bytesvalue_converter(CConverter):
2339 type = 'int'
2340 converter = '_getbytevalue'
2341[python start generated code]*/
2342/*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
2343
2344
2345/*[clinic input]
2346bytearray.insert
2347
2348 self: self(type="PyByteArrayObject *")
2349 index: Py_ssize_t
2350 The index where the value is to be inserted.
2351 item: bytesvalue
2352 The item to be inserted.
2353 /
2354
2355Insert a single item into the bytearray before the given index.
2356[clinic start generated code]*/
2357
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002358static PyObject *
2359bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002360/*[clinic end generated code: output=76c775a70e7b07b7 input=833766836ba30e1e]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002361{
2362 Py_ssize_t n = Py_SIZE(self);
2363 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002364
2365 if (n == PY_SSIZE_T_MAX) {
2366 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002367 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002368 return NULL;
2369 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002370 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2371 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002372 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002373
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002374 if (index < 0) {
2375 index += n;
2376 if (index < 0)
2377 index = 0;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002378 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002379 if (index > n)
2380 index = n;
2381 memmove(buf + index + 1, buf + index, n - index);
2382 buf[index] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002383
2384 Py_RETURN_NONE;
2385}
2386
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002387/*[clinic input]
2388bytearray.append
2389
2390 self: self(type="PyByteArrayObject *")
2391 item: bytesvalue
2392 The item to be appended.
2393 /
2394
2395Append a single item to the end of the bytearray.
2396[clinic start generated code]*/
2397
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002398static PyObject *
2399bytearray_append_impl(PyByteArrayObject *self, int item)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002400/*[clinic end generated code: output=a154e19ed1886cb6 input=ae56ea87380407cc]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002401{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002402 Py_ssize_t n = Py_SIZE(self);
2403
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002404 if (n == PY_SSIZE_T_MAX) {
2405 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002406 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002407 return NULL;
2408 }
2409 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2410 return NULL;
2411
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002412 PyByteArray_AS_STRING(self)[n] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002413
2414 Py_RETURN_NONE;
2415}
2416
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002417/*[clinic input]
2418bytearray.extend
2419
2420 self: self(type="PyByteArrayObject *")
2421 iterable_of_ints: object
2422 The iterable of items to append.
2423 /
2424
2425Append all the items from the iterator or sequence to the end of the bytearray.
2426[clinic start generated code]*/
2427
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002428static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002429bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002430/*[clinic end generated code: output=98155dbe249170b1 input=ce83a5d75b70d850]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002431{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002432 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002433 Py_ssize_t buf_size = 0, len = 0;
2434 int value;
2435 char *buf;
2436
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002437 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002438 if (PyObject_CheckBuffer(iterable_of_ints)) {
2439 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002440 return NULL;
2441
2442 Py_RETURN_NONE;
2443 }
2444
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002445 it = PyObject_GetIter(iterable_of_ints);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002446 if (it == NULL)
2447 return NULL;
2448
Ezio Melotti42da6632011-03-15 05:18:48 +02002449 /* Try to determine the length of the argument. 32 is arbitrary. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002450 buf_size = PyObject_LengthHint(iterable_of_ints, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002451 if (buf_size == -1) {
2452 Py_DECREF(it);
2453 return NULL;
2454 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002455
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002456 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002457 if (bytearray_obj == NULL) {
2458 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002459 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002460 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002461 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002462
2463 while ((item = PyIter_Next(it)) != NULL) {
2464 if (! _getbytevalue(item, &value)) {
2465 Py_DECREF(item);
2466 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002467 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002468 return NULL;
2469 }
2470 buf[len++] = value;
2471 Py_DECREF(item);
2472
2473 if (len >= buf_size) {
2474 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002475 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002476 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002477 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002478 return NULL;
2479 }
2480 /* Recompute the `buf' pointer, since the resizing operation may
2481 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002482 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002483 }
2484 }
2485 Py_DECREF(it);
2486
2487 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002488 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2489 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002490 return NULL;
2491 }
2492
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002493 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2494 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002495 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002496 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002497 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002498
2499 Py_RETURN_NONE;
2500}
2501
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002502/*[clinic input]
2503bytearray.pop
2504
2505 self: self(type="PyByteArrayObject *")
2506 index: Py_ssize_t = -1
2507 The index from where to remove the item.
2508 -1 (the default value) means remove the last item.
2509 /
2510
2511Remove and return a single item from B.
2512
2513If no index argument is given, will pop the last item.
2514[clinic start generated code]*/
2515
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002516static PyObject *
2517bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002518/*[clinic end generated code: output=e0ccd401f8021da8 input=0797e6c0ca9d5a85]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002519{
2520 int value;
2521 Py_ssize_t n = Py_SIZE(self);
2522 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002523
2524 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002525 PyErr_SetString(PyExc_IndexError,
2526 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002527 return NULL;
2528 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002529 if (index < 0)
2530 index += Py_SIZE(self);
2531 if (index < 0 || index >= Py_SIZE(self)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002532 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2533 return NULL;
2534 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002535 if (!_canresize(self))
2536 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002537
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002538 buf = PyByteArray_AS_STRING(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002539 value = buf[index];
2540 memmove(buf + index, buf + index + 1, n - index);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002541 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2542 return NULL;
2543
Mark Dickinson54a3db92009-09-06 10:19:23 +00002544 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002545}
2546
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002547/*[clinic input]
2548bytearray.remove
2549
2550 self: self(type="PyByteArrayObject *")
2551 value: bytesvalue
2552 The value to remove.
2553 /
2554
2555Remove the first occurrence of a value in the bytearray.
2556[clinic start generated code]*/
2557
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002558static PyObject *
2559bytearray_remove_impl(PyByteArrayObject *self, int value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002560/*[clinic end generated code: output=d659e37866709c13 input=47560b11fd856c24]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002561{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002562 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002563 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002564
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002565 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002566 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002567 break;
2568 }
2569 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002570 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002571 return NULL;
2572 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002573 if (!_canresize(self))
2574 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002575
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002576 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002577 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2578 return NULL;
2579
2580 Py_RETURN_NONE;
2581}
2582
2583/* XXX These two helpers could be optimized if argsize == 1 */
2584
2585static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002586lstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002587 void *argptr, Py_ssize_t argsize)
2588{
2589 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002590 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002591 i++;
2592 return i;
2593}
2594
2595static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002596rstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002597 void *argptr, Py_ssize_t argsize)
2598{
2599 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002600 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002601 i--;
2602 return i + 1;
2603}
2604
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002605/*[clinic input]
2606bytearray.strip
2607
2608 bytes: object = None
2609 /
2610
2611Strip leading and trailing bytes contained in the argument.
2612
2613If the argument is omitted or None, strip leading and trailing ASCII whitespace.
2614[clinic start generated code]*/
2615
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002616static PyObject *
2617bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002618/*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002619{
2620 Py_ssize_t left, right, mysize, byteslen;
2621 char *myptr, *bytesptr;
2622 Py_buffer vbytes;
2623
2624 if (bytes == Py_None) {
2625 bytesptr = "\t\n\r\f\v ";
2626 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002627 }
2628 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002629 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002630 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002631 bytesptr = (char *) vbytes.buf;
2632 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002633 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002634 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002635 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002636 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002637 if (left == mysize)
2638 right = left;
2639 else
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002640 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
2641 if (bytes != Py_None)
2642 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002643 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002644}
2645
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002646/*[clinic input]
2647bytearray.lstrip
2648
2649 bytes: object = None
2650 /
2651
2652Strip leading bytes contained in the argument.
2653
2654If the argument is omitted or None, strip leading ASCII whitespace.
2655[clinic start generated code]*/
2656
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002657static PyObject *
2658bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002659/*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002660{
2661 Py_ssize_t left, right, mysize, byteslen;
2662 char *myptr, *bytesptr;
2663 Py_buffer vbytes;
2664
2665 if (bytes == Py_None) {
2666 bytesptr = "\t\n\r\f\v ";
2667 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002668 }
2669 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002670 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002671 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002672 bytesptr = (char *) vbytes.buf;
2673 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002674 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002675 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002676 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002677 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002678 right = mysize;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002679 if (bytes != Py_None)
2680 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002681 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002682}
2683
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002684/*[clinic input]
2685bytearray.rstrip
2686
2687 bytes: object = None
2688 /
2689
2690Strip trailing bytes contained in the argument.
2691
2692If the argument is omitted or None, strip trailing ASCII whitespace.
2693[clinic start generated code]*/
2694
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002695static PyObject *
2696bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002697/*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002698{
2699 Py_ssize_t right, mysize, byteslen;
2700 char *myptr, *bytesptr;
2701 Py_buffer vbytes;
2702
2703 if (bytes == Py_None) {
2704 bytesptr = "\t\n\r\f\v ";
2705 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002706 }
2707 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002708 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002709 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002710 bytesptr = (char *) vbytes.buf;
2711 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002712 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002713 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002714 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002715 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
2716 if (bytes != Py_None)
2717 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002718 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002719}
2720
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002721/*[clinic input]
2722bytearray.decode
2723
2724 encoding: str(c_default="NULL") = 'utf-8'
2725 The encoding with which to decode the bytearray.
2726 errors: str(c_default="NULL") = 'strict'
2727 The error handling scheme to use for the handling of decoding errors.
2728 The default is 'strict' meaning that decoding errors raise a
2729 UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
2730 as well as any other name registered with codecs.register_error that
2731 can handle UnicodeDecodeErrors.
2732
2733Decode the bytearray using the codec registered for encoding.
2734[clinic start generated code]*/
2735
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002736static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002737bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
2738 const char *errors)
2739/*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002740{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002741 if (encoding == NULL)
2742 encoding = PyUnicode_GetDefaultEncoding();
Martin v. Löwis0efea322014-07-27 17:29:17 +02002743 return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002744}
2745
2746PyDoc_STRVAR(alloc_doc,
2747"B.__alloc__() -> int\n\
2748\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002749Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002750
2751static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002752bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002753{
2754 return PyLong_FromSsize_t(self->ob_alloc);
2755}
2756
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002757/*[clinic input]
2758bytearray.join
2759
2760 iterable_of_bytes: object
2761 /
2762
2763Concatenate any number of bytes/bytearray objects.
2764
2765The bytearray whose method is called is inserted in between each pair.
2766
2767The result is returned as a new bytearray object.
2768[clinic start generated code]*/
2769
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002770static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002771bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002772/*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002773{
Martin v. Löwis0efea322014-07-27 17:29:17 +02002774 return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002775}
2776
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002777/*[clinic input]
2778bytearray.splitlines
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002779
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002780 keepends: int(py_default="False") = 0
2781
2782Return a list of the lines in the bytearray, breaking at line boundaries.
2783
2784Line breaks are not included in the resulting list unless keepends is given and
2785true.
2786[clinic start generated code]*/
2787
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002788static PyObject *
2789bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002790/*[clinic end generated code: output=4223c94b895f6ad9 input=36f0b25bc792f6c0]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002791{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002792 return stringlib_splitlines(
2793 (PyObject*) self, PyByteArray_AS_STRING(self),
2794 PyByteArray_GET_SIZE(self), keepends
2795 );
2796}
2797
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002798static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002799hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002800{
2801 if (c >= 128)
2802 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002803 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002804 return c - '0';
2805 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002806 if (Py_ISUPPER(c))
2807 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002808 if (c >= 'a' && c <= 'f')
2809 return c - 'a' + 10;
2810 }
2811 return -1;
2812}
2813
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002814/*[clinic input]
2815@classmethod
2816bytearray.fromhex
2817
2818 cls: self(type="PyObject*")
2819 string: unicode
2820 /
2821
2822Create a bytearray object from a string of hexadecimal numbers.
2823
2824Spaces between two numbers are accepted.
2825Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
2826[clinic start generated code]*/
2827
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002828static PyObject *
2829bytearray_fromhex_impl(PyObject*cls, PyObject *string)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002830/*[clinic end generated code: output=df3da60129b3700c input=907bbd2d34d9367a]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002831{
2832 PyObject *newbytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002833 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002834 Py_ssize_t hexlen, byteslen, i, j;
2835 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002836 void *data;
2837 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002838
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002839 assert(PyUnicode_Check(string));
2840 if (PyUnicode_READY(string))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002841 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002842 kind = PyUnicode_KIND(string);
2843 data = PyUnicode_DATA(string);
2844 hexlen = PyUnicode_GET_LENGTH(string);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002845
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002846 byteslen = hexlen/2; /* This overestimates if there are spaces */
2847 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2848 if (!newbytes)
2849 return NULL;
2850 buf = PyByteArray_AS_STRING(newbytes);
2851 for (i = j = 0; i < hexlen; i += 2) {
2852 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002853 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002854 i++;
2855 if (i >= hexlen)
2856 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002857 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2858 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002859 if (top == -1 || bot == -1) {
2860 PyErr_Format(PyExc_ValueError,
2861 "non-hexadecimal number found in "
2862 "fromhex() arg at position %zd", i);
2863 goto error;
2864 }
2865 buf[j++] = (top << 4) + bot;
2866 }
2867 if (PyByteArray_Resize(newbytes, j) < 0)
2868 goto error;
2869 return newbytes;
2870
2871 error:
2872 Py_DECREF(newbytes);
2873 return NULL;
2874}
2875
Gregory P. Smith8cb65692015-04-25 23:22:26 +00002876PyDoc_STRVAR(hex__doc__,
2877"B.hex() -> string\n\
2878\n\
2879Create a string of hexadecimal numbers from a bytearray object.\n\
2880Example: bytearray([0xb9, 0x01, 0xef]).hex() -> 'b901ef'.");
2881
2882static PyObject *
2883bytearray_hex(PyBytesObject *self)
2884{
2885 char* argbuf = PyByteArray_AS_STRING(self);
2886 Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
2887 return _Py_strhex(argbuf, arglen);
2888}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002889
2890static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002891_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002892{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002893 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002894 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002895 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002896
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002897 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002898 if (dict == NULL) {
2899 PyErr_Clear();
2900 dict = Py_None;
2901 Py_INCREF(dict);
2902 }
2903
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002904 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002905 if (proto < 3) {
2906 /* use str based reduction for backwards compatibility with Python 2.x */
2907 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002908 if (Py_SIZE(self))
2909 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002910 else
2911 latin1 = PyUnicode_FromString("");
2912 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2913 }
2914 else {
2915 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002916 if (Py_SIZE(self)) {
2917 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002918 }
2919 else {
2920 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2921 }
2922 }
2923}
2924
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002925/*[clinic input]
2926bytearray.__reduce__ as bytearray_reduce
2927
2928 self: self(type="PyByteArrayObject *")
2929
2930Return state information for pickling.
2931[clinic start generated code]*/
2932
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002933static PyObject *
2934bytearray_reduce_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002935/*[clinic end generated code: output=52bf304086464cab input=fbb07de4d102a03a]*/
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002936{
2937 return _common_reduce(self, 2);
2938}
2939
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002940/*[clinic input]
2941bytearray.__reduce_ex__ as bytearray_reduce_ex
2942
2943 self: self(type="PyByteArrayObject *")
2944 proto: int = 0
2945 /
2946
2947Return state information for pickling.
2948[clinic start generated code]*/
2949
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002950static PyObject *
2951bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002952/*[clinic end generated code: output=52eac33377197520 input=0e091a42ca6dbd91]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002953{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002954 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002955}
2956
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002957/*[clinic input]
2958bytearray.__sizeof__ as bytearray_sizeof
2959
2960 self: self(type="PyByteArrayObject *")
2961
2962Returns the size of the bytearray object in memory, in bytes.
2963[clinic start generated code]*/
2964
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002965static PyObject *
2966bytearray_sizeof_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002967/*[clinic end generated code: output=738abdd17951c427 input=6b23d305362b462b]*/
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002968{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002969 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002970
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002971 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2972 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002973}
2974
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002975static PySequenceMethods bytearray_as_sequence = {
2976 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002977 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002978 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2979 (ssizeargfunc)bytearray_getitem, /* sq_item */
2980 0, /* sq_slice */
2981 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2982 0, /* sq_ass_slice */
2983 (objobjproc)bytearray_contains, /* sq_contains */
2984 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2985 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002986};
2987
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002988static PyMappingMethods bytearray_as_mapping = {
2989 (lenfunc)bytearray_length,
2990 (binaryfunc)bytearray_subscript,
2991 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002992};
2993
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002994static PyBufferProcs bytearray_as_buffer = {
2995 (getbufferproc)bytearray_getbuffer,
2996 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002997};
2998
2999static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003000bytearray_methods[] = {
3001 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003002 BYTEARRAY_REDUCE_METHODDEF
3003 BYTEARRAY_REDUCE_EX_METHODDEF
3004 BYTEARRAY_SIZEOF_METHODDEF
3005 BYTEARRAY_APPEND_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003006 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
3007 _Py_capitalize__doc__},
3008 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003009 BYTEARRAY_CLEAR_METHODDEF
3010 BYTEARRAY_COPY_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003011 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003012 BYTEARRAY_DECODE_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003013 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Ezio Melotti745d54d2013-11-16 19:10:57 +02003014 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003015 expandtabs__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003016 BYTEARRAY_EXTEND_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003017 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003018 BYTEARRAY_FROMHEX_METHODDEF
Gregory P. Smith8cb65692015-04-25 23:22:26 +00003019 {"hex", (PyCFunction)bytearray_hex, METH_NOARGS, hex__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003020 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003021 BYTEARRAY_INSERT_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003022 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
3023 _Py_isalnum__doc__},
3024 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
3025 _Py_isalpha__doc__},
3026 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
3027 _Py_isdigit__doc__},
3028 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
3029 _Py_islower__doc__},
3030 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
3031 _Py_isspace__doc__},
3032 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
3033 _Py_istitle__doc__},
3034 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
3035 _Py_isupper__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003036 BYTEARRAY_JOIN_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003037 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
3038 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003039 BYTEARRAY_LSTRIP_METHODDEF
3040 BYTEARRAY_MAKETRANS_METHODDEF
3041 BYTEARRAY_PARTITION_METHODDEF
3042 BYTEARRAY_POP_METHODDEF
3043 BYTEARRAY_REMOVE_METHODDEF
3044 BYTEARRAY_REPLACE_METHODDEF
3045 BYTEARRAY_REVERSE_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003046 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
3047 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003048 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003049 BYTEARRAY_RPARTITION_METHODDEF
3050 BYTEARRAY_RSPLIT_METHODDEF
3051 BYTEARRAY_RSTRIP_METHODDEF
3052 BYTEARRAY_SPLIT_METHODDEF
3053 BYTEARRAY_SPLITLINES_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003054 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003055 startswith__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003056 BYTEARRAY_STRIP_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003057 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
3058 _Py_swapcase__doc__},
3059 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003060 BYTEARRAY_TRANSLATE_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003061 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
3062 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
3063 {NULL}
3064};
3065
Ethan Furmanb95b5612015-01-23 20:05:18 -08003066static PyObject *
3067bytearray_mod(PyObject *v, PyObject *w)
3068{
3069 if (!PyByteArray_Check(v))
3070 Py_RETURN_NOTIMPLEMENTED;
3071 return bytearray_format((PyByteArrayObject *)v, w);
3072}
3073
3074static PyNumberMethods bytearray_as_number = {
3075 0, /*nb_add*/
3076 0, /*nb_subtract*/
3077 0, /*nb_multiply*/
3078 bytearray_mod, /*nb_remainder*/
3079};
3080
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003081PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00003082"bytearray(iterable_of_ints) -> bytearray\n\
3083bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003084bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
3085bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
3086bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003087\n\
3088Construct an mutable bytearray object from:\n\
3089 - an iterable yielding integers in range(256)\n\
3090 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003091 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003092 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003093 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003094
3095
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003096static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003097
3098PyTypeObject PyByteArray_Type = {
3099 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3100 "bytearray",
3101 sizeof(PyByteArrayObject),
3102 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003103 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003104 0, /* tp_print */
3105 0, /* tp_getattr */
3106 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003107 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003108 (reprfunc)bytearray_repr, /* tp_repr */
Ethan Furmanb95b5612015-01-23 20:05:18 -08003109 &bytearray_as_number, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003110 &bytearray_as_sequence, /* tp_as_sequence */
3111 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003112 0, /* tp_hash */
3113 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003114 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003115 PyObject_GenericGetAttr, /* tp_getattro */
3116 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003117 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003118 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003119 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003120 0, /* tp_traverse */
3121 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003122 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003123 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003124 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003125 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003126 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003127 0, /* tp_members */
3128 0, /* tp_getset */
3129 0, /* tp_base */
3130 0, /* tp_dict */
3131 0, /* tp_descr_get */
3132 0, /* tp_descr_set */
3133 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003134 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003135 PyType_GenericAlloc, /* tp_alloc */
3136 PyType_GenericNew, /* tp_new */
3137 PyObject_Del, /* tp_free */
3138};
3139
3140/*********************** Bytes Iterator ****************************/
3141
3142typedef struct {
3143 PyObject_HEAD
3144 Py_ssize_t it_index;
3145 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
3146} bytesiterobject;
3147
3148static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003149bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003150{
3151 _PyObject_GC_UNTRACK(it);
3152 Py_XDECREF(it->it_seq);
3153 PyObject_GC_Del(it);
3154}
3155
3156static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003157bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003158{
3159 Py_VISIT(it->it_seq);
3160 return 0;
3161}
3162
3163static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003164bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003165{
3166 PyByteArrayObject *seq;
3167 PyObject *item;
3168
3169 assert(it != NULL);
3170 seq = it->it_seq;
3171 if (seq == NULL)
3172 return NULL;
3173 assert(PyByteArray_Check(seq));
3174
3175 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
3176 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003177 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003178 if (item != NULL)
3179 ++it->it_index;
3180 return item;
3181 }
3182
3183 Py_DECREF(seq);
3184 it->it_seq = NULL;
3185 return NULL;
3186}
3187
3188static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003189bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003190{
3191 Py_ssize_t len = 0;
3192 if (it->it_seq)
3193 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3194 return PyLong_FromSsize_t(len);
3195}
3196
3197PyDoc_STRVAR(length_hint_doc,
3198 "Private method returning an estimate of len(list(it)).");
3199
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003200static PyObject *
3201bytearrayiter_reduce(bytesiterobject *it)
3202{
3203 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02003204 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003205 it->it_seq, it->it_index);
3206 } else {
3207 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
3208 if (u == NULL)
3209 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02003210 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003211 }
3212}
3213
3214static PyObject *
3215bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3216{
3217 Py_ssize_t index = PyLong_AsSsize_t(state);
3218 if (index == -1 && PyErr_Occurred())
3219 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +00003220 if (it->it_seq != NULL) {
3221 if (index < 0)
3222 index = 0;
3223 else if (index > PyByteArray_GET_SIZE(it->it_seq))
3224 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
3225 it->it_index = index;
3226 }
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003227 Py_RETURN_NONE;
3228}
3229
3230PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3231
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003232static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003233 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003234 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003235 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003236 bytearray_reduce__doc__},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003237 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3238 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003239 {NULL, NULL} /* sentinel */
3240};
3241
3242PyTypeObject PyByteArrayIter_Type = {
3243 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3244 "bytearray_iterator", /* tp_name */
3245 sizeof(bytesiterobject), /* tp_basicsize */
3246 0, /* tp_itemsize */
3247 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003248 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003249 0, /* tp_print */
3250 0, /* tp_getattr */
3251 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003252 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003253 0, /* tp_repr */
3254 0, /* tp_as_number */
3255 0, /* tp_as_sequence */
3256 0, /* tp_as_mapping */
3257 0, /* tp_hash */
3258 0, /* tp_call */
3259 0, /* tp_str */
3260 PyObject_GenericGetAttr, /* tp_getattro */
3261 0, /* tp_setattro */
3262 0, /* tp_as_buffer */
3263 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3264 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003265 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003266 0, /* tp_clear */
3267 0, /* tp_richcompare */
3268 0, /* tp_weaklistoffset */
3269 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003270 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3271 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003272 0,
3273};
3274
3275static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003276bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003277{
3278 bytesiterobject *it;
3279
3280 if (!PyByteArray_Check(seq)) {
3281 PyErr_BadInternalCall();
3282 return NULL;
3283 }
3284 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3285 if (it == NULL)
3286 return NULL;
3287 it->it_index = 0;
3288 Py_INCREF(seq);
3289 it->it_seq = (PyByteArrayObject *)seq;
3290 _PyObject_GC_TRACK(it);
3291 return (PyObject *)it;
3292}