blob: b9477ca9f5658581ed6abbd2da9a5ae155f0cac2 [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 Pitrou25454112015-05-19 20:52:27 +0200190 if (size + logical_offset + 1 <= alloc) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200191 /* 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 }
Antoine Pitrou25454112015-05-19 20:52:27 +0200334 if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000335 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000336 return NULL;
337 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200338 memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000339 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000340 Py_INCREF(self);
341 return (PyObject *)self;
342}
343
344static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000345bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000346{
347 PyByteArrayObject *result;
348 Py_ssize_t mysize;
349 Py_ssize_t size;
350
351 if (count < 0)
352 count = 0;
353 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000354 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000355 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000356 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000357 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
358 if (result != NULL && size != 0) {
359 if (mysize == 1)
360 memset(result->ob_bytes, self->ob_bytes[0], size);
361 else {
362 Py_ssize_t i;
363 for (i = 0; i < count; i++)
364 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
365 }
366 }
367 return (PyObject *)result;
368}
369
370static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000371bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000372{
373 Py_ssize_t mysize;
374 Py_ssize_t size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200375 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000376
377 if (count < 0)
378 count = 0;
379 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000380 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000381 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000382 size = mysize * count;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200383 if (PyByteArray_Resize((PyObject *)self, size) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000384 return NULL;
385
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200386 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000387 if (mysize == 1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200388 memset(buf, buf[0], size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000389 else {
390 Py_ssize_t i;
391 for (i = 1; i < count; i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200392 memcpy(buf + i*mysize, buf, mysize);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000393 }
394
395 Py_INCREF(self);
396 return (PyObject *)self;
397}
398
399static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000400bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000401{
402 if (i < 0)
403 i += Py_SIZE(self);
404 if (i < 0 || i >= Py_SIZE(self)) {
405 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
406 return NULL;
407 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200408 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000409}
410
411static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000412bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000413{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000414 if (PyIndex_Check(index)) {
415 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000416
417 if (i == -1 && PyErr_Occurred())
418 return NULL;
419
420 if (i < 0)
421 i += PyByteArray_GET_SIZE(self);
422
423 if (i < 0 || i >= Py_SIZE(self)) {
424 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
425 return NULL;
426 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200427 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000428 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000429 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000430 Py_ssize_t start, stop, step, slicelength, cur, i;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000431 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000432 PyByteArray_GET_SIZE(self),
433 &start, &stop, &step, &slicelength) < 0) {
434 return NULL;
435 }
436
437 if (slicelength <= 0)
438 return PyByteArray_FromStringAndSize("", 0);
439 else if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200440 return PyByteArray_FromStringAndSize(
441 PyByteArray_AS_STRING(self) + start, slicelength);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000442 }
443 else {
444 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000445 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000446 PyObject *result;
447
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000448 result = PyByteArray_FromStringAndSize(NULL, slicelength);
449 if (result == NULL)
450 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000451
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000452 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000453 for (cur = start, i = 0; i < slicelength;
454 cur += step, i++) {
455 result_buf[i] = source_buf[cur];
456 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000457 return result;
458 }
459 }
460 else {
Terry Jan Reedyffff1442014-08-02 01:30:37 -0400461 PyErr_Format(PyExc_TypeError,
462 "bytearray indices must be integers or slices, not %.200s",
463 Py_TYPE(index)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000464 return NULL;
465 }
466}
467
468static int
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200469bytearray_setslice_linear(PyByteArrayObject *self,
470 Py_ssize_t lo, Py_ssize_t hi,
471 char *bytes, Py_ssize_t bytes_len)
472{
473 Py_ssize_t avail = hi - lo;
474 char *buf = PyByteArray_AS_STRING(self);
475 Py_ssize_t growth = bytes_len - avail;
Victor Stinner84557232013-11-21 12:29:51 +0100476 int res = 0;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200477 assert(avail >= 0);
478
Victor Stinner84557232013-11-21 12:29:51 +0100479 if (growth < 0) {
480 if (!_canresize(self))
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200481 return -1;
Victor Stinner84557232013-11-21 12:29:51 +0100482
483 if (lo == 0) {
484 /* Shrink the buffer by advancing its logical start */
485 self->ob_start -= growth;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200486 /*
Victor Stinner84557232013-11-21 12:29:51 +0100487 0 lo hi old_size
488 | |<----avail----->|<-----tail------>|
489 | |<-bytes_len->|<-----tail------>|
490 0 new_lo new_hi new_size
491 */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200492 }
Victor Stinner84557232013-11-21 12:29:51 +0100493 else {
494 /*
495 0 lo hi old_size
496 | |<----avail----->|<-----tomove------>|
497 | |<-bytes_len->|<-----tomove------>|
498 0 lo new_hi new_size
499 */
500 memmove(buf + lo + bytes_len, buf + hi,
501 Py_SIZE(self) - hi);
502 }
503 if (PyByteArray_Resize((PyObject *)self,
504 Py_SIZE(self) + growth) < 0) {
505 /* Issue #19578: Handling the memory allocation failure here is
506 tricky here because the bytearray object has already been
507 modified. Depending on growth and lo, the behaviour is
508 different.
509
510 If growth < 0 and lo != 0, the operation is completed, but a
511 MemoryError is still raised and the memory block is not
512 shrinked. Otherwise, the bytearray is restored in its previous
513 state and a MemoryError is raised. */
514 if (lo == 0) {
515 self->ob_start += growth;
516 return -1;
517 }
518 /* memmove() removed bytes, the bytearray object cannot be
519 restored in its previous state. */
520 Py_SIZE(self) += growth;
521 res = -1;
522 }
523 buf = PyByteArray_AS_STRING(self);
524 }
525 else if (growth > 0) {
526 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
527 PyErr_NoMemory();
528 return -1;
529 }
530
531 if (PyByteArray_Resize((PyObject *)self,
532 Py_SIZE(self) + growth) < 0) {
533 return -1;
534 }
535 buf = PyByteArray_AS_STRING(self);
536 /* Make the place for the additional bytes */
537 /*
538 0 lo hi old_size
539 | |<-avail->|<-----tomove------>|
540 | |<---bytes_len-->|<-----tomove------>|
541 0 lo new_hi new_size
542 */
543 memmove(buf + lo + bytes_len, buf + hi,
544 Py_SIZE(self) - lo - bytes_len);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200545 }
546
547 if (bytes_len > 0)
548 memcpy(buf + lo, bytes, bytes_len);
Victor Stinner84557232013-11-21 12:29:51 +0100549 return res;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200550}
551
552static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000553bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000554 PyObject *values)
555{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200556 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000557 void *bytes;
558 Py_buffer vbytes;
559 int res = 0;
560
561 vbytes.len = -1;
562 if (values == (PyObject *)self) {
563 /* Make a copy and call this function recursively */
564 int err;
565 values = PyByteArray_FromObject(values);
566 if (values == NULL)
567 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000568 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000569 Py_DECREF(values);
570 return err;
571 }
572 if (values == NULL) {
573 /* del b[lo:hi] */
574 bytes = NULL;
575 needed = 0;
576 }
577 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200578 if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
579 PyErr_Format(PyExc_TypeError,
580 "can't set bytearray slice from %.100s",
581 Py_TYPE(values)->tp_name);
582 return -1;
583 }
584 needed = vbytes.len;
585 bytes = vbytes.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000586 }
587
588 if (lo < 0)
589 lo = 0;
590 if (hi < lo)
591 hi = lo;
592 if (hi > Py_SIZE(self))
593 hi = Py_SIZE(self);
594
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200595 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000596 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200597 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000598 return res;
599}
600
601static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000602bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000603{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000604 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000605
606 if (i < 0)
607 i += Py_SIZE(self);
608
609 if (i < 0 || i >= Py_SIZE(self)) {
610 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
611 return -1;
612 }
613
614 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000615 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000616
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000617 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000618 return -1;
619
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200620 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000621 return 0;
622}
623
624static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000625bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000626{
627 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200628 char *buf, *bytes;
629 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000630
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000631 if (PyIndex_Check(index)) {
632 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000633
634 if (i == -1 && PyErr_Occurred())
635 return -1;
636
637 if (i < 0)
638 i += PyByteArray_GET_SIZE(self);
639
640 if (i < 0 || i >= Py_SIZE(self)) {
641 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
642 return -1;
643 }
644
645 if (values == NULL) {
646 /* Fall through to slice assignment */
647 start = i;
648 stop = i + 1;
649 step = 1;
650 slicelen = 1;
651 }
652 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000653 int ival;
654 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000655 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200656 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000657 return 0;
658 }
659 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000660 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000661 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000662 PyByteArray_GET_SIZE(self),
663 &start, &stop, &step, &slicelen) < 0) {
664 return -1;
665 }
666 }
667 else {
Terry Jan Reedyffff1442014-08-02 01:30:37 -0400668 PyErr_Format(PyExc_TypeError,
669 "bytearray indices must be integers or slices, not %.200s",
670 Py_TYPE(index)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000671 return -1;
672 }
673
674 if (values == NULL) {
675 bytes = NULL;
676 needed = 0;
677 }
678 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100679 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200680 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
681 PyErr_SetString(PyExc_TypeError,
682 "can assign only bytes, buffers, or iterables "
683 "of ints in range(0, 256)");
684 return -1;
685 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000686 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000687 values = PyByteArray_FromObject(values);
688 if (values == NULL)
689 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000690 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000691 Py_DECREF(values);
692 return err;
693 }
694 else {
695 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200696 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000697 needed = Py_SIZE(values);
698 }
699 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
700 if ((step < 0 && start < stop) ||
701 (step > 0 && start > stop))
702 stop = start;
703 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200704 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000705 }
706 else {
707 if (needed == 0) {
708 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000709 size_t cur;
710 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000711
Antoine Pitrou5504e892008-12-06 21:27:53 +0000712 if (!_canresize(self))
713 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000714
715 if (slicelen == 0)
716 /* Nothing to do here. */
717 return 0;
718
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000719 if (step < 0) {
720 stop = start + 1;
721 start = stop + step * (slicelen - 1) - 1;
722 step = -step;
723 }
724 for (cur = start, i = 0;
725 i < slicelen; cur += step, i++) {
726 Py_ssize_t lim = step - 1;
727
Mark Dickinson66f575b2010-02-14 12:53:32 +0000728 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000729 lim = PyByteArray_GET_SIZE(self) - cur - 1;
730
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200731 memmove(buf + cur - i,
732 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000733 }
734 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000735 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000736 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200737 memmove(buf + cur - slicelen,
738 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000739 PyByteArray_GET_SIZE(self) - cur);
740 }
741 if (PyByteArray_Resize((PyObject *)self,
742 PyByteArray_GET_SIZE(self) - slicelen) < 0)
743 return -1;
744
745 return 0;
746 }
747 else {
748 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000749 Py_ssize_t i;
750 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000751
752 if (needed != slicelen) {
753 PyErr_Format(PyExc_ValueError,
754 "attempt to assign bytes of size %zd "
755 "to extended slice of size %zd",
756 needed, slicelen);
757 return -1;
758 }
759 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200760 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000761 return 0;
762 }
763 }
764}
765
766static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000767bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000768{
769 static char *kwlist[] = {"source", "encoding", "errors", 0};
770 PyObject *arg = NULL;
771 const char *encoding = NULL;
772 const char *errors = NULL;
773 Py_ssize_t count;
774 PyObject *it;
775 PyObject *(*iternext)(PyObject *);
776
777 if (Py_SIZE(self) != 0) {
778 /* Empty previous contents (yes, do this first of all!) */
779 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
780 return -1;
781 }
782
783 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000784 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000785 &arg, &encoding, &errors))
786 return -1;
787
788 /* Make a quick exit if no first argument */
789 if (arg == NULL) {
790 if (encoding != NULL || errors != NULL) {
791 PyErr_SetString(PyExc_TypeError,
792 "encoding or errors without sequence argument");
793 return -1;
794 }
795 return 0;
796 }
797
798 if (PyUnicode_Check(arg)) {
799 /* Encode via the codec registry */
800 PyObject *encoded, *new;
801 if (encoding == NULL) {
802 PyErr_SetString(PyExc_TypeError,
803 "string argument without an encoding");
804 return -1;
805 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000806 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000807 if (encoded == NULL)
808 return -1;
809 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000810 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000811 Py_DECREF(encoded);
812 if (new == NULL)
813 return -1;
814 Py_DECREF(new);
815 return 0;
816 }
817
818 /* If it's not unicode, there can't be encoding or errors */
819 if (encoding != NULL || errors != NULL) {
820 PyErr_SetString(PyExc_TypeError,
821 "encoding or errors without a string argument");
822 return -1;
823 }
824
825 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000826 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
827 if (count == -1 && PyErr_Occurred()) {
828 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000829 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000830 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000831 }
832 else if (count < 0) {
833 PyErr_SetString(PyExc_ValueError, "negative count");
834 return -1;
835 }
836 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000837 if (count > 0) {
Victor Stinner2bc4d952014-06-02 22:22:42 +0200838 if (PyByteArray_Resize((PyObject *)self, count))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000839 return -1;
Victor Stinner2bc4d952014-06-02 22:22:42 +0200840 memset(PyByteArray_AS_STRING(self), 0, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000841 }
842 return 0;
843 }
844
845 /* Use the buffer API */
846 if (PyObject_CheckBuffer(arg)) {
847 Py_ssize_t size;
848 Py_buffer view;
849 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
850 return -1;
851 size = view.len;
852 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200853 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
854 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200855 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000856 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000857 return 0;
858 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000859 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000860 return -1;
861 }
862
863 /* XXX Optimize this if the arguments is a list, tuple */
864
865 /* Get the iterator */
866 it = PyObject_GetIter(arg);
867 if (it == NULL)
868 return -1;
869 iternext = *Py_TYPE(it)->tp_iternext;
870
871 /* Run the iterator to exhaustion */
872 for (;;) {
873 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000874 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000875
876 /* Get the next item */
877 item = iternext(it);
878 if (item == NULL) {
879 if (PyErr_Occurred()) {
880 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
881 goto error;
882 PyErr_Clear();
883 }
884 break;
885 }
886
887 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000888 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000889 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000890 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000891 goto error;
892
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000893 /* Append the byte */
894 if (Py_SIZE(self) < self->ob_alloc)
895 Py_SIZE(self)++;
896 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
897 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200898 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000899 }
900
901 /* Clean up and return success */
902 Py_DECREF(it);
903 return 0;
904
905 error:
906 /* Error handling when it != NULL */
907 Py_DECREF(it);
908 return -1;
909}
910
911/* Mostly copied from string_repr, but without the
912 "smart quote" functionality. */
913static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000914bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000915{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000916 const char *quote_prefix = "bytearray(b";
917 const char *quote_postfix = ")";
918 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200919 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000920 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000921 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200922 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200923 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200924 char c;
925 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200926 int quote;
927 char *test, *start;
928 char *buffer;
929
930 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000931 PyErr_SetString(PyExc_OverflowError,
932 "bytearray object is too large to make repr");
933 return NULL;
934 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200935
936 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100937 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200938 if (buffer == NULL) {
939 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000940 return NULL;
941 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000942
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200943 /* Figure out which quote to use; single is preferred */
944 quote = '\'';
945 start = PyByteArray_AS_STRING(self);
946 for (test = start; test < start+length; ++test) {
947 if (*test == '"') {
948 quote = '\''; /* back to single */
949 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000950 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200951 else if (*test == '\'')
952 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000953 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200954
955 p = buffer;
956 while (*quote_prefix)
957 *p++ = *quote_prefix++;
958 *p++ = quote;
959
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200960 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200961 for (i = 0; i < length; i++) {
962 /* There's at least enough room for a hex escape
963 and a closing quote. */
964 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200965 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200966 if (c == '\'' || c == '\\')
967 *p++ = '\\', *p++ = c;
968 else if (c == '\t')
969 *p++ = '\\', *p++ = 't';
970 else if (c == '\n')
971 *p++ = '\\', *p++ = 'n';
972 else if (c == '\r')
973 *p++ = '\\', *p++ = 'r';
974 else if (c == 0)
975 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
976 else if (c < ' ' || c >= 0x7f) {
977 *p++ = '\\';
978 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200979 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
980 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200981 }
982 else
983 *p++ = c;
984 }
985 assert(newsize - (p - buffer) >= 1);
986 *p++ = quote;
987 while (*quote_postfix) {
988 *p++ = *quote_postfix++;
989 }
990
991 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100992 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200993 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000994}
995
996static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000997bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000998{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000999 if (Py_BytesWarningFlag) {
1000 if (PyErr_WarnEx(PyExc_BytesWarning,
1001 "str() on a bytearray instance", 1))
1002 return NULL;
1003 }
1004 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001005}
1006
1007static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001008bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001009{
1010 Py_ssize_t self_size, other_size;
1011 Py_buffer self_bytes, other_bytes;
1012 PyObject *res;
1013 Py_ssize_t minsize;
1014 int cmp;
1015
1016 /* Bytes can be compared to anything that supports the (binary)
1017 buffer API. Except that a comparison with Unicode is always an
1018 error, even if the comparison is for equality. */
1019 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1020 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +00001021 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001022 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +00001023 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001024 return NULL;
1025 }
1026
Brian Curtindfc80e32011-08-10 20:28:54 -05001027 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001028 }
1029
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001030 if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001031 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -05001032 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001033 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001034 self_size = self_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001035
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001036 if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001037 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001038 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001039 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001040 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001041 other_size = other_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001042
1043 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1044 /* Shortcut: if the lengths differ, the objects differ */
1045 cmp = (op == Py_NE);
1046 }
1047 else {
1048 minsize = self_size;
1049 if (other_size < minsize)
1050 minsize = other_size;
1051
1052 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1053 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1054
1055 if (cmp == 0) {
1056 if (self_size < other_size)
1057 cmp = -1;
1058 else if (self_size > other_size)
1059 cmp = 1;
1060 }
1061
1062 switch (op) {
1063 case Py_LT: cmp = cmp < 0; break;
1064 case Py_LE: cmp = cmp <= 0; break;
1065 case Py_EQ: cmp = cmp == 0; break;
1066 case Py_NE: cmp = cmp != 0; break;
1067 case Py_GT: cmp = cmp > 0; break;
1068 case Py_GE: cmp = cmp >= 0; break;
1069 }
1070 }
1071
1072 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001073 PyBuffer_Release(&self_bytes);
1074 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001075 Py_INCREF(res);
1076 return res;
1077}
1078
1079static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001080bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001081{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001082 if (self->ob_exports > 0) {
1083 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001084 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001085 PyErr_Print();
1086 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001087 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001088 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001089 }
1090 Py_TYPE(self)->tp_free((PyObject *)self);
1091}
1092
1093
1094/* -------------------------------------------------------------------- */
1095/* Methods */
1096
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001097#define FASTSEARCH fastsearch
1098#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001099#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001100#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001101#define STRINGLIB_LEN PyByteArray_GET_SIZE
1102#define STRINGLIB_STR PyByteArray_AS_STRING
1103#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001104#define STRINGLIB_ISSPACE Py_ISSPACE
1105#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001106#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1107#define STRINGLIB_MUTABLE 1
1108
1109#include "stringlib/fastsearch.h"
1110#include "stringlib/count.h"
1111#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001112#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001113#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001114#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001115#include "stringlib/ctype.h"
1116#include "stringlib/transmogrify.h"
1117
1118
1119/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1120were copied from the old char* style string object. */
1121
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001122/* helper macro to fixup start/end slice values */
1123#define ADJUST_INDICES(start, end, len) \
1124 if (end > len) \
1125 end = len; \
1126 else if (end < 0) { \
1127 end += len; \
1128 if (end < 0) \
1129 end = 0; \
1130 } \
1131 if (start < 0) { \
1132 start += len; \
1133 if (start < 0) \
1134 start = 0; \
1135 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001136
1137Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001138bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001139{
1140 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001141 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001142 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001143 const char *sub;
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001144 Py_ssize_t len, sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001145 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1146 Py_ssize_t res;
1147
Antoine Pitrouac65d962011-10-20 23:54:17 +02001148 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1149 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001150 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001151
1152 if (subobj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001153 if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001154 return -2;
1155
1156 sub = subbuf.buf;
1157 sub_len = subbuf.len;
1158 }
1159 else {
1160 sub = &byte;
1161 sub_len = 1;
1162 }
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001163 len = PyByteArray_GET_SIZE(self);
Antoine Pitrouac65d962011-10-20 23:54:17 +02001164
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001165 ADJUST_INDICES(start, end, len);
1166 if (end - start < sub_len)
1167 res = -1;
Victor Stinnerdabbfe72015-03-25 03:16:32 +01001168 /* Issue #23573: FIXME, windows has no memrchr() */
1169 else if (sub_len == 1 && dir > 0) {
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001170 unsigned char needle = *sub;
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001171 res = stringlib_fastsearch_memchr_1char(
1172 PyByteArray_AS_STRING(self) + start, end - start,
Christian Heimes4e259132015-04-18 05:54:02 +02001173 needle, needle, FAST_SEARCH);
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001174 if (res >= 0)
1175 res += start;
1176 }
1177 else {
1178 if (dir > 0)
1179 res = stringlib_find_slice(
1180 PyByteArray_AS_STRING(self), len,
1181 sub, sub_len, start, end);
1182 else
1183 res = stringlib_rfind_slice(
1184 PyByteArray_AS_STRING(self), len,
1185 sub, sub_len, start, end);
1186 }
Antoine Pitrouac65d962011-10-20 23:54:17 +02001187
1188 if (subobj)
1189 PyBuffer_Release(&subbuf);
1190
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001191 return res;
1192}
1193
1194PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001195"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001196\n\
1197Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001198such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001199arguments start and end are interpreted as in slice notation.\n\
1200\n\
1201Return -1 on failure.");
1202
1203static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001204bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001205{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001206 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001207 if (result == -2)
1208 return NULL;
1209 return PyLong_FromSsize_t(result);
1210}
1211
1212PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001213"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001214\n\
1215Return the number of non-overlapping occurrences of subsection sub in\n\
1216bytes B[start:end]. Optional arguments start and end are interpreted\n\
1217as in slice notation.");
1218
1219static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001220bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001221{
1222 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001223 const char *str = PyByteArray_AS_STRING(self), *sub;
1224 Py_ssize_t sub_len;
1225 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001226 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001227
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001228 Py_buffer vsub;
1229 PyObject *count_obj;
1230
Antoine Pitrouac65d962011-10-20 23:54:17 +02001231 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1232 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001233 return NULL;
1234
Antoine Pitrouac65d962011-10-20 23:54:17 +02001235 if (sub_obj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001236 if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001237 return NULL;
1238
1239 sub = vsub.buf;
1240 sub_len = vsub.len;
1241 }
1242 else {
1243 sub = &byte;
1244 sub_len = 1;
1245 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001246
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001247 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001248
1249 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001250 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001251 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001252
1253 if (sub_obj)
1254 PyBuffer_Release(&vsub);
1255
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001256 return count_obj;
1257}
1258
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001259/*[clinic input]
1260bytearray.clear
1261
1262 self: self(type="PyByteArrayObject *")
1263
1264Remove all items from the bytearray.
1265[clinic start generated code]*/
1266
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001267static PyObject *
1268bytearray_clear_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001269/*[clinic end generated code: output=85c2fe6aede0956c input=e524fd330abcdc18]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001270{
1271 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1272 return NULL;
1273 Py_RETURN_NONE;
1274}
1275
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001276/*[clinic input]
1277bytearray.copy
1278
1279 self: self(type="PyByteArrayObject *")
1280
1281Return a copy of B.
1282[clinic start generated code]*/
1283
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001284static PyObject *
1285bytearray_copy_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001286/*[clinic end generated code: output=68cfbcfed484c132 input=6d5d2975aa0f33f3]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001287{
1288 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1289 PyByteArray_GET_SIZE(self));
1290}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001291
1292PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001293"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001294\n\
1295Like B.find() but raise ValueError when the subsection is not found.");
1296
1297static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001298bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001299{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001300 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001301 if (result == -2)
1302 return NULL;
1303 if (result == -1) {
1304 PyErr_SetString(PyExc_ValueError,
1305 "subsection not found");
1306 return NULL;
1307 }
1308 return PyLong_FromSsize_t(result);
1309}
1310
1311
1312PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001313"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001314\n\
1315Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001316such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001317arguments start and end are interpreted as in slice notation.\n\
1318\n\
1319Return -1 on failure.");
1320
1321static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001322bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001323{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001324 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001325 if (result == -2)
1326 return NULL;
1327 return PyLong_FromSsize_t(result);
1328}
1329
1330
1331PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001332"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001333\n\
1334Like B.rfind() but raise ValueError when the subsection is not found.");
1335
1336static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001337bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001338{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001339 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001340 if (result == -2)
1341 return NULL;
1342 if (result == -1) {
1343 PyErr_SetString(PyExc_ValueError,
1344 "subsection not found");
1345 return NULL;
1346 }
1347 return PyLong_FromSsize_t(result);
1348}
1349
1350
1351static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001352bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001353{
1354 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1355 if (ival == -1 && PyErr_Occurred()) {
1356 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001357 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001358 PyErr_Clear();
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001359 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001360 return -1;
1361 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1362 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001363 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001364 return pos >= 0;
1365 }
1366 if (ival < 0 || ival >= 256) {
1367 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1368 return -1;
1369 }
1370
Antoine Pitrou0010d372010-08-15 17:12:55 +00001371 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001372}
1373
1374
1375/* Matches the end (direction >= 0) or start (direction < 0) of self
1376 * against substr, using the start and end arguments. Returns
1377 * -1 on error, 0 if not found and 1 if found.
1378 */
1379Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001380_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001381 Py_ssize_t end, int direction)
1382{
1383 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1384 const char* str;
1385 Py_buffer vsubstr;
1386 int rv = 0;
1387
1388 str = PyByteArray_AS_STRING(self);
1389
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001390 if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001391 return -1;
1392
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001393 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001394
1395 if (direction < 0) {
1396 /* startswith */
1397 if (start+vsubstr.len > len) {
1398 goto done;
1399 }
1400 } else {
1401 /* endswith */
1402 if (end-start < vsubstr.len || start > len) {
1403 goto done;
1404 }
1405
1406 if (end-vsubstr.len > start)
1407 start = end - vsubstr.len;
1408 }
1409 if (end-start >= vsubstr.len)
1410 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1411
1412done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001413 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001414 return rv;
1415}
1416
1417
1418PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001419"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001420\n\
1421Return True if B starts with the specified prefix, False otherwise.\n\
1422With optional start, test B beginning at that position.\n\
1423With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001424prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001425
1426static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001427bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001428{
1429 Py_ssize_t start = 0;
1430 Py_ssize_t end = PY_SSIZE_T_MAX;
1431 PyObject *subobj;
1432 int result;
1433
Jesus Ceaac451502011-04-20 17:09:23 +02001434 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001435 return NULL;
1436 if (PyTuple_Check(subobj)) {
1437 Py_ssize_t i;
1438 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001439 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001440 PyTuple_GET_ITEM(subobj, i),
1441 start, end, -1);
1442 if (result == -1)
1443 return NULL;
1444 else if (result) {
1445 Py_RETURN_TRUE;
1446 }
1447 }
1448 Py_RETURN_FALSE;
1449 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001450 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001451 if (result == -1) {
1452 if (PyErr_ExceptionMatches(PyExc_TypeError))
1453 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1454 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001455 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001456 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001457 else
1458 return PyBool_FromLong(result);
1459}
1460
1461PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001462"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001463\n\
1464Return True if B ends with the specified suffix, False otherwise.\n\
1465With optional start, test B beginning at that position.\n\
1466With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001467suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001468
1469static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001470bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001471{
1472 Py_ssize_t start = 0;
1473 Py_ssize_t end = PY_SSIZE_T_MAX;
1474 PyObject *subobj;
1475 int result;
1476
Jesus Ceaac451502011-04-20 17:09:23 +02001477 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001478 return NULL;
1479 if (PyTuple_Check(subobj)) {
1480 Py_ssize_t i;
1481 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001482 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001483 PyTuple_GET_ITEM(subobj, i),
1484 start, end, +1);
1485 if (result == -1)
1486 return NULL;
1487 else if (result) {
1488 Py_RETURN_TRUE;
1489 }
1490 }
1491 Py_RETURN_FALSE;
1492 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001493 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001494 if (result == -1) {
1495 if (PyErr_ExceptionMatches(PyExc_TypeError))
1496 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1497 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001498 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001499 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001500 else
1501 return PyBool_FromLong(result);
1502}
1503
1504
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001505/*[clinic input]
1506bytearray.translate
1507
1508 self: self(type="PyByteArrayObject *")
1509 table: object
1510 Translation table, which must be a bytes object of length 256.
1511 [
1512 deletechars: object
1513 ]
1514 /
1515
1516Return a copy with each character mapped by the given translation table.
1517
1518All characters occurring in the optional argument deletechars are removed.
1519The remaining characters are mapped through the given translation table.
1520[clinic start generated code]*/
1521
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001522static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001523bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
1524 int group_right_1, PyObject *deletechars)
1525/*[clinic end generated code: output=2bebc86a9a1ff083 input=b749ad85f4860824]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001526{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001527 char *input, *output;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001528 const char *table_chars;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001529 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001530 PyObject *input_obj = (PyObject*)self;
1531 const char *output_start;
1532 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001533 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001534 int trans_table[256];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001535 Py_buffer vtable, vdel;
1536
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001537 if (table == Py_None) {
1538 table_chars = NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001539 table = NULL;
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001540 } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001541 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001542 } else {
1543 if (vtable.len != 256) {
1544 PyErr_SetString(PyExc_ValueError,
1545 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001546 PyBuffer_Release(&vtable);
1547 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001548 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001549 table_chars = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001550 }
1551
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001552 if (deletechars != NULL) {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001553 if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001554 if (table != NULL)
Georg Brandl953152f2009-07-22 12:03:59 +00001555 PyBuffer_Release(&vtable);
1556 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001557 }
1558 }
1559 else {
1560 vdel.buf = NULL;
1561 vdel.len = 0;
1562 }
1563
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001564 inlen = PyByteArray_GET_SIZE(input_obj);
1565 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1566 if (result == NULL)
1567 goto done;
1568 output_start = output = PyByteArray_AsString(result);
1569 input = PyByteArray_AS_STRING(input_obj);
1570
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001571 if (vdel.len == 0 && table_chars != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001572 /* If no deletions are required, use faster code */
1573 for (i = inlen; --i >= 0; ) {
1574 c = Py_CHARMASK(*input++);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001575 *output++ = table_chars[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001576 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001577 goto done;
1578 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001579
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001580 if (table_chars == NULL) {
Georg Brandlccc47b62008-12-28 11:44:14 +00001581 for (i = 0; i < 256; i++)
1582 trans_table[i] = Py_CHARMASK(i);
1583 } else {
1584 for (i = 0; i < 256; i++)
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001585 trans_table[i] = Py_CHARMASK(table_chars[i]);
Georg Brandlccc47b62008-12-28 11:44:14 +00001586 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001587
1588 for (i = 0; i < vdel.len; i++)
1589 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1590
1591 for (i = inlen; --i >= 0; ) {
1592 c = Py_CHARMASK(*input++);
1593 if (trans_table[c] != -1)
1594 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1595 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001596 }
1597 /* Fix the size of the resulting string */
1598 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001599 if (PyByteArray_Resize(result, output - output_start) < 0) {
1600 Py_CLEAR(result);
1601 goto done;
1602 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001603
1604done:
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001605 if (table != NULL)
Georg Brandlccc47b62008-12-28 11:44:14 +00001606 PyBuffer_Release(&vtable);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001607 if (deletechars != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001608 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001609 return result;
1610}
1611
1612
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001613/*[clinic input]
1614
1615@staticmethod
1616bytearray.maketrans
1617
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001618 frm: Py_buffer
1619 to: Py_buffer
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001620 /
1621
1622Return a translation table useable for the bytes or bytearray translate method.
1623
1624The returned table will be one where each byte in frm is mapped to the byte at
1625the same position in to.
1626
1627The bytes objects frm and to must be of the same length.
1628[clinic start generated code]*/
1629
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001630static PyObject *
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001631bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001632/*[clinic end generated code: output=1df267d99f56b15e input=5925a81d2fbbf151]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001633{
1634 return _Py_bytes_maketrans(frm, to);
Georg Brandlabc38772009-04-12 15:51:51 +00001635}
1636
1637
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001638/* find and count characters and substrings */
1639
1640#define findchar(target, target_len, c) \
1641 ((char *)memchr((const void *)(target), c, target_len))
1642
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001643
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001644/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001645Py_LOCAL(PyByteArrayObject *)
1646return_self(PyByteArrayObject *self)
1647{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001648 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001649 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1650 PyByteArray_AS_STRING(self),
1651 PyByteArray_GET_SIZE(self));
1652}
1653
1654Py_LOCAL_INLINE(Py_ssize_t)
1655countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1656{
1657 Py_ssize_t count=0;
1658 const char *start=target;
1659 const char *end=target+target_len;
1660
1661 while ( (start=findchar(start, end-start, c)) != NULL ) {
1662 count++;
1663 if (count >= maxcount)
1664 break;
1665 start += 1;
1666 }
1667 return count;
1668}
1669
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001670
1671/* Algorithms for different cases of string replacement */
1672
1673/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1674Py_LOCAL(PyByteArrayObject *)
1675replace_interleave(PyByteArrayObject *self,
1676 const char *to_s, Py_ssize_t to_len,
1677 Py_ssize_t maxcount)
1678{
1679 char *self_s, *result_s;
1680 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001681 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001682 PyByteArrayObject *result;
1683
1684 self_len = PyByteArray_GET_SIZE(self);
1685
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001686 /* 1 at the end plus 1 after every character;
1687 count = min(maxcount, self_len + 1) */
1688 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001689 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001690 else
1691 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1692 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001693
1694 /* Check for overflow */
1695 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001696 assert(count > 0);
1697 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001698 PyErr_SetString(PyExc_OverflowError,
1699 "replace string is too long");
1700 return NULL;
1701 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001702 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001703
1704 if (! (result = (PyByteArrayObject *)
1705 PyByteArray_FromStringAndSize(NULL, result_len)) )
1706 return NULL;
1707
1708 self_s = PyByteArray_AS_STRING(self);
1709 result_s = PyByteArray_AS_STRING(result);
1710
1711 /* TODO: special case single character, which doesn't need memcpy */
1712
1713 /* Lay the first one down (guaranteed this will occur) */
1714 Py_MEMCPY(result_s, to_s, to_len);
1715 result_s += to_len;
1716 count -= 1;
1717
1718 for (i=0; i<count; i++) {
1719 *result_s++ = *self_s++;
1720 Py_MEMCPY(result_s, to_s, to_len);
1721 result_s += to_len;
1722 }
1723
1724 /* Copy the rest of the original string */
1725 Py_MEMCPY(result_s, self_s, self_len-i);
1726
1727 return result;
1728}
1729
1730/* Special case for deleting a single character */
1731/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1732Py_LOCAL(PyByteArrayObject *)
1733replace_delete_single_character(PyByteArrayObject *self,
1734 char from_c, Py_ssize_t maxcount)
1735{
1736 char *self_s, *result_s;
1737 char *start, *next, *end;
1738 Py_ssize_t self_len, result_len;
1739 Py_ssize_t count;
1740 PyByteArrayObject *result;
1741
1742 self_len = PyByteArray_GET_SIZE(self);
1743 self_s = PyByteArray_AS_STRING(self);
1744
1745 count = countchar(self_s, self_len, from_c, maxcount);
1746 if (count == 0) {
1747 return return_self(self);
1748 }
1749
1750 result_len = self_len - count; /* from_len == 1 */
1751 assert(result_len>=0);
1752
1753 if ( (result = (PyByteArrayObject *)
1754 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1755 return NULL;
1756 result_s = PyByteArray_AS_STRING(result);
1757
1758 start = self_s;
1759 end = self_s + self_len;
1760 while (count-- > 0) {
1761 next = findchar(start, end-start, from_c);
1762 if (next == NULL)
1763 break;
1764 Py_MEMCPY(result_s, start, next-start);
1765 result_s += (next-start);
1766 start = next+1;
1767 }
1768 Py_MEMCPY(result_s, start, end-start);
1769
1770 return result;
1771}
1772
1773/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1774
1775Py_LOCAL(PyByteArrayObject *)
1776replace_delete_substring(PyByteArrayObject *self,
1777 const char *from_s, Py_ssize_t from_len,
1778 Py_ssize_t maxcount)
1779{
1780 char *self_s, *result_s;
1781 char *start, *next, *end;
1782 Py_ssize_t self_len, result_len;
1783 Py_ssize_t count, offset;
1784 PyByteArrayObject *result;
1785
1786 self_len = PyByteArray_GET_SIZE(self);
1787 self_s = PyByteArray_AS_STRING(self);
1788
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001789 count = stringlib_count(self_s, self_len,
1790 from_s, from_len,
1791 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001792
1793 if (count == 0) {
1794 /* no matches */
1795 return return_self(self);
1796 }
1797
1798 result_len = self_len - (count * from_len);
1799 assert (result_len>=0);
1800
1801 if ( (result = (PyByteArrayObject *)
1802 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1803 return NULL;
1804
1805 result_s = PyByteArray_AS_STRING(result);
1806
1807 start = self_s;
1808 end = self_s + self_len;
1809 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001810 offset = stringlib_find(start, end-start,
1811 from_s, from_len,
1812 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001813 if (offset == -1)
1814 break;
1815 next = start + offset;
1816
1817 Py_MEMCPY(result_s, start, next-start);
1818
1819 result_s += (next-start);
1820 start = next+from_len;
1821 }
1822 Py_MEMCPY(result_s, start, end-start);
1823 return result;
1824}
1825
1826/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1827Py_LOCAL(PyByteArrayObject *)
1828replace_single_character_in_place(PyByteArrayObject *self,
1829 char from_c, char to_c,
1830 Py_ssize_t maxcount)
1831{
Antoine Pitroud1188562010-06-09 16:38:55 +00001832 char *self_s, *result_s, *start, *end, *next;
1833 Py_ssize_t self_len;
1834 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001835
Antoine Pitroud1188562010-06-09 16:38:55 +00001836 /* The result string will be the same size */
1837 self_s = PyByteArray_AS_STRING(self);
1838 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001839
Antoine Pitroud1188562010-06-09 16:38:55 +00001840 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001841
Antoine Pitroud1188562010-06-09 16:38:55 +00001842 if (next == NULL) {
1843 /* No matches; return the original bytes */
1844 return return_self(self);
1845 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001846
Antoine Pitroud1188562010-06-09 16:38:55 +00001847 /* Need to make a new bytes */
1848 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1849 if (result == NULL)
1850 return NULL;
1851 result_s = PyByteArray_AS_STRING(result);
1852 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001853
Antoine Pitroud1188562010-06-09 16:38:55 +00001854 /* change everything in-place, starting with this one */
1855 start = result_s + (next-self_s);
1856 *start = to_c;
1857 start++;
1858 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001859
Antoine Pitroud1188562010-06-09 16:38:55 +00001860 while (--maxcount > 0) {
1861 next = findchar(start, end-start, from_c);
1862 if (next == NULL)
1863 break;
1864 *next = to_c;
1865 start = next+1;
1866 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001867
Antoine Pitroud1188562010-06-09 16:38:55 +00001868 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001869}
1870
1871/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1872Py_LOCAL(PyByteArrayObject *)
1873replace_substring_in_place(PyByteArrayObject *self,
1874 const char *from_s, Py_ssize_t from_len,
1875 const char *to_s, Py_ssize_t to_len,
1876 Py_ssize_t maxcount)
1877{
1878 char *result_s, *start, *end;
1879 char *self_s;
1880 Py_ssize_t self_len, offset;
1881 PyByteArrayObject *result;
1882
1883 /* The result bytes will be the same size */
1884
1885 self_s = PyByteArray_AS_STRING(self);
1886 self_len = PyByteArray_GET_SIZE(self);
1887
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001888 offset = stringlib_find(self_s, self_len,
1889 from_s, from_len,
1890 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001891 if (offset == -1) {
1892 /* No matches; return the original bytes */
1893 return return_self(self);
1894 }
1895
1896 /* Need to make a new bytes */
1897 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1898 if (result == NULL)
1899 return NULL;
1900 result_s = PyByteArray_AS_STRING(result);
1901 Py_MEMCPY(result_s, self_s, self_len);
1902
1903 /* change everything in-place, starting with this one */
1904 start = result_s + offset;
1905 Py_MEMCPY(start, to_s, from_len);
1906 start += from_len;
1907 end = result_s + self_len;
1908
1909 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001910 offset = stringlib_find(start, end-start,
1911 from_s, from_len,
1912 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001913 if (offset==-1)
1914 break;
1915 Py_MEMCPY(start+offset, to_s, from_len);
1916 start += offset+from_len;
1917 }
1918
1919 return result;
1920}
1921
1922/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1923Py_LOCAL(PyByteArrayObject *)
1924replace_single_character(PyByteArrayObject *self,
1925 char from_c,
1926 const char *to_s, Py_ssize_t to_len,
1927 Py_ssize_t maxcount)
1928{
1929 char *self_s, *result_s;
1930 char *start, *next, *end;
1931 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001932 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001933 PyByteArrayObject *result;
1934
1935 self_s = PyByteArray_AS_STRING(self);
1936 self_len = PyByteArray_GET_SIZE(self);
1937
1938 count = countchar(self_s, self_len, from_c, maxcount);
1939 if (count == 0) {
1940 /* no matches, return unchanged */
1941 return return_self(self);
1942 }
1943
1944 /* use the difference between current and new, hence the "-1" */
1945 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001946 assert(count > 0);
1947 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001948 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1949 return NULL;
1950 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001951 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001952
1953 if ( (result = (PyByteArrayObject *)
1954 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1955 return NULL;
1956 result_s = PyByteArray_AS_STRING(result);
1957
1958 start = self_s;
1959 end = self_s + self_len;
1960 while (count-- > 0) {
1961 next = findchar(start, end-start, from_c);
1962 if (next == NULL)
1963 break;
1964
1965 if (next == start) {
1966 /* replace with the 'to' */
1967 Py_MEMCPY(result_s, to_s, to_len);
1968 result_s += to_len;
1969 start += 1;
1970 } else {
1971 /* copy the unchanged old then the 'to' */
1972 Py_MEMCPY(result_s, start, next-start);
1973 result_s += (next-start);
1974 Py_MEMCPY(result_s, to_s, to_len);
1975 result_s += to_len;
1976 start = next+1;
1977 }
1978 }
1979 /* Copy the remainder of the remaining bytes */
1980 Py_MEMCPY(result_s, start, end-start);
1981
1982 return result;
1983}
1984
1985/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1986Py_LOCAL(PyByteArrayObject *)
1987replace_substring(PyByteArrayObject *self,
1988 const char *from_s, Py_ssize_t from_len,
1989 const char *to_s, Py_ssize_t to_len,
1990 Py_ssize_t maxcount)
1991{
1992 char *self_s, *result_s;
1993 char *start, *next, *end;
1994 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001995 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001996 PyByteArrayObject *result;
1997
1998 self_s = PyByteArray_AS_STRING(self);
1999 self_len = PyByteArray_GET_SIZE(self);
2000
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002001 count = stringlib_count(self_s, self_len,
2002 from_s, from_len,
2003 maxcount);
2004
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002005 if (count == 0) {
2006 /* no matches, return unchanged */
2007 return return_self(self);
2008 }
2009
2010 /* Check for overflow */
2011 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002012 assert(count > 0);
2013 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002014 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
2015 return NULL;
2016 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002017 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002018
2019 if ( (result = (PyByteArrayObject *)
2020 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
2021 return NULL;
2022 result_s = PyByteArray_AS_STRING(result);
2023
2024 start = self_s;
2025 end = self_s + self_len;
2026 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002027 offset = stringlib_find(start, end-start,
2028 from_s, from_len,
2029 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002030 if (offset == -1)
2031 break;
2032 next = start+offset;
2033 if (next == start) {
2034 /* replace with the 'to' */
2035 Py_MEMCPY(result_s, to_s, to_len);
2036 result_s += to_len;
2037 start += from_len;
2038 } else {
2039 /* copy the unchanged old then the 'to' */
2040 Py_MEMCPY(result_s, start, next-start);
2041 result_s += (next-start);
2042 Py_MEMCPY(result_s, to_s, to_len);
2043 result_s += to_len;
2044 start = next+from_len;
2045 }
2046 }
2047 /* Copy the remainder of the remaining bytes */
2048 Py_MEMCPY(result_s, start, end-start);
2049
2050 return result;
2051}
2052
2053
2054Py_LOCAL(PyByteArrayObject *)
2055replace(PyByteArrayObject *self,
2056 const char *from_s, Py_ssize_t from_len,
2057 const char *to_s, Py_ssize_t to_len,
2058 Py_ssize_t maxcount)
2059{
2060 if (maxcount < 0) {
2061 maxcount = PY_SSIZE_T_MAX;
2062 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
2063 /* nothing to do; return the original bytes */
2064 return return_self(self);
2065 }
2066
2067 if (maxcount == 0 ||
2068 (from_len == 0 && to_len == 0)) {
2069 /* nothing to do; return the original bytes */
2070 return return_self(self);
2071 }
2072
2073 /* Handle zero-length special cases */
2074
2075 if (from_len == 0) {
2076 /* insert the 'to' bytes everywhere. */
2077 /* >>> "Python".replace("", ".") */
2078 /* '.P.y.t.h.o.n.' */
2079 return replace_interleave(self, to_s, to_len, maxcount);
2080 }
2081
2082 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2083 /* point for an empty self bytes to generate a non-empty bytes */
2084 /* Special case so the remaining code always gets a non-empty bytes */
2085 if (PyByteArray_GET_SIZE(self) == 0) {
2086 return return_self(self);
2087 }
2088
2089 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002090 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002091 if (from_len == 1) {
2092 return replace_delete_single_character(
2093 self, from_s[0], maxcount);
2094 } else {
2095 return replace_delete_substring(self, from_s, from_len, maxcount);
2096 }
2097 }
2098
2099 /* Handle special case where both bytes have the same length */
2100
2101 if (from_len == to_len) {
2102 if (from_len == 1) {
2103 return replace_single_character_in_place(
2104 self,
2105 from_s[0],
2106 to_s[0],
2107 maxcount);
2108 } else {
2109 return replace_substring_in_place(
2110 self, from_s, from_len, to_s, to_len, maxcount);
2111 }
2112 }
2113
2114 /* Otherwise use the more generic algorithms */
2115 if (from_len == 1) {
2116 return replace_single_character(self, from_s[0],
2117 to_s, to_len, maxcount);
2118 } else {
2119 /* len('from')>=2, len('to')>=1 */
2120 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2121 }
2122}
2123
2124
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002125/*[clinic input]
2126bytearray.replace
2127
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002128 old: Py_buffer
2129 new: Py_buffer
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002130 count: Py_ssize_t = -1
2131 Maximum number of occurrences to replace.
2132 -1 (the default value) means replace all occurrences.
2133 /
2134
2135Return a copy with all occurrences of substring old replaced by new.
2136
2137If the optional argument count is given, only the first count occurrences are
2138replaced.
2139[clinic start generated code]*/
2140
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002141static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002142bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old,
2143 Py_buffer *new, Py_ssize_t count)
2144/*[clinic end generated code: output=d39884c4dc59412a input=aa379d988637c7fb]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002145{
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002146 return (PyObject *)replace((PyByteArrayObject *) self,
2147 old->buf, old->len,
2148 new->buf, new->len, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002149}
2150
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002151/*[clinic input]
2152bytearray.split
2153
2154 sep: object = None
2155 The delimiter according which to split the bytearray.
2156 None (the default value) means split on ASCII whitespace characters
2157 (space, tab, return, newline, formfeed, vertical tab).
2158 maxsplit: Py_ssize_t = -1
2159 Maximum number of splits to do.
2160 -1 (the default value) means no limit.
2161
2162Return a list of the sections in the bytearray, using sep as the delimiter.
2163[clinic start generated code]*/
2164
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002165static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002166bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
2167 Py_ssize_t maxsplit)
2168/*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002169{
2170 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002171 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002172 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002173 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002174
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002175 if (maxsplit < 0)
2176 maxsplit = PY_SSIZE_T_MAX;
2177
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002178 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002179 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002180
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002181 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002182 return NULL;
2183 sub = vsub.buf;
2184 n = vsub.len;
2185
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002186 list = stringlib_split(
2187 (PyObject*) self, s, len, sub, n, maxsplit
2188 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002189 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002190 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002191}
2192
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002193/*[clinic input]
2194bytearray.partition
2195
2196 self: self(type="PyByteArrayObject *")
2197 sep: object
2198 /
2199
2200Partition the bytearray into three parts using the given separator.
2201
2202This will search for the separator sep in the bytearray. If the separator is
2203found, returns a 3-tuple containing the part before the separator, the
2204separator itself, and the part after it.
2205
2206If the separator is not found, returns a 3-tuple containing the original
2207bytearray object and two empty bytearray objects.
2208[clinic start generated code]*/
2209
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002210static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002211bytearray_partition(PyByteArrayObject *self, PyObject *sep)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002212/*[clinic end generated code: output=45d2525ddd35f957 input=7d7fe37b1696d506]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002213{
2214 PyObject *bytesep, *result;
2215
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002216 bytesep = PyByteArray_FromObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002217 if (! bytesep)
2218 return NULL;
2219
2220 result = stringlib_partition(
2221 (PyObject*) self,
2222 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2223 bytesep,
2224 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2225 );
2226
2227 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002228 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002229}
2230
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002231/*[clinic input]
2232bytearray.rpartition
2233
2234 self: self(type="PyByteArrayObject *")
2235 sep: object
2236 /
2237
2238Partition the bytes into three parts using the given separator.
2239
2240This will search for the separator sep in the bytearray, starting and the end.
2241If the separator is found, returns a 3-tuple containing the part before the
2242separator, the separator itself, and the part after it.
2243
2244If the separator is not found, returns a 3-tuple containing two empty bytearray
2245objects and the original bytearray object.
2246[clinic start generated code]*/
2247
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002248static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002249bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002250/*[clinic end generated code: output=440de3c9426115e8 input=9b8cd540c1b75853]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002251{
2252 PyObject *bytesep, *result;
2253
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002254 bytesep = PyByteArray_FromObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002255 if (! bytesep)
2256 return NULL;
2257
2258 result = stringlib_rpartition(
2259 (PyObject*) self,
2260 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2261 bytesep,
2262 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2263 );
2264
2265 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002266 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002267}
2268
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002269/*[clinic input]
2270bytearray.rsplit = bytearray.split
2271
2272Return a list of the sections in the bytearray, using sep as the delimiter.
2273
2274Splitting is done starting at the end of the bytearray and working to the front.
2275[clinic start generated code]*/
2276
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002277static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002278bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
2279 Py_ssize_t maxsplit)
2280/*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002281{
2282 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002283 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002284 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002285 Py_buffer vsub;
2286
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002287 if (maxsplit < 0)
2288 maxsplit = PY_SSIZE_T_MAX;
2289
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002290 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002291 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002292
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002293 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002294 return NULL;
2295 sub = vsub.buf;
2296 n = vsub.len;
2297
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002298 list = stringlib_rsplit(
2299 (PyObject*) self, s, len, sub, n, maxsplit
2300 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002301 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002302 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002303}
2304
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002305/*[clinic input]
2306bytearray.reverse
2307
2308 self: self(type="PyByteArrayObject *")
2309
2310Reverse the order of the values in B in place.
2311[clinic start generated code]*/
2312
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002313static PyObject *
2314bytearray_reverse_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002315/*[clinic end generated code: output=9f7616f29ab309d3 input=7933a499b8597bd1]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002316{
2317 char swap, *head, *tail;
2318 Py_ssize_t i, j, n = Py_SIZE(self);
2319
2320 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002321 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002322 tail = head + n - 1;
2323 for (i = 0; i < j; i++) {
2324 swap = *head;
2325 *head++ = *tail;
2326 *tail-- = swap;
2327 }
2328
2329 Py_RETURN_NONE;
2330}
2331
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002332
2333/*[python input]
2334class bytesvalue_converter(CConverter):
2335 type = 'int'
2336 converter = '_getbytevalue'
2337[python start generated code]*/
2338/*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
2339
2340
2341/*[clinic input]
2342bytearray.insert
2343
2344 self: self(type="PyByteArrayObject *")
2345 index: Py_ssize_t
2346 The index where the value is to be inserted.
2347 item: bytesvalue
2348 The item to be inserted.
2349 /
2350
2351Insert a single item into the bytearray before the given index.
2352[clinic start generated code]*/
2353
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002354static PyObject *
2355bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002356/*[clinic end generated code: output=76c775a70e7b07b7 input=833766836ba30e1e]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002357{
2358 Py_ssize_t n = Py_SIZE(self);
2359 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002360
2361 if (n == PY_SSIZE_T_MAX) {
2362 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002363 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002364 return NULL;
2365 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002366 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2367 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002368 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002369
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002370 if (index < 0) {
2371 index += n;
2372 if (index < 0)
2373 index = 0;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002374 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002375 if (index > n)
2376 index = n;
2377 memmove(buf + index + 1, buf + index, n - index);
2378 buf[index] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002379
2380 Py_RETURN_NONE;
2381}
2382
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002383/*[clinic input]
2384bytearray.append
2385
2386 self: self(type="PyByteArrayObject *")
2387 item: bytesvalue
2388 The item to be appended.
2389 /
2390
2391Append a single item to the end of the bytearray.
2392[clinic start generated code]*/
2393
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002394static PyObject *
2395bytearray_append_impl(PyByteArrayObject *self, int item)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002396/*[clinic end generated code: output=a154e19ed1886cb6 input=ae56ea87380407cc]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002397{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002398 Py_ssize_t n = Py_SIZE(self);
2399
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002400 if (n == PY_SSIZE_T_MAX) {
2401 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002402 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002403 return NULL;
2404 }
2405 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2406 return NULL;
2407
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002408 PyByteArray_AS_STRING(self)[n] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002409
2410 Py_RETURN_NONE;
2411}
2412
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002413/*[clinic input]
2414bytearray.extend
2415
2416 self: self(type="PyByteArrayObject *")
2417 iterable_of_ints: object
2418 The iterable of items to append.
2419 /
2420
2421Append all the items from the iterator or sequence to the end of the bytearray.
2422[clinic start generated code]*/
2423
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002424static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002425bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002426/*[clinic end generated code: output=98155dbe249170b1 input=ce83a5d75b70d850]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002427{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002428 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002429 Py_ssize_t buf_size = 0, len = 0;
2430 int value;
2431 char *buf;
2432
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002433 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002434 if (PyObject_CheckBuffer(iterable_of_ints)) {
2435 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002436 return NULL;
2437
2438 Py_RETURN_NONE;
2439 }
2440
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002441 it = PyObject_GetIter(iterable_of_ints);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002442 if (it == NULL)
2443 return NULL;
2444
Ezio Melotti42da6632011-03-15 05:18:48 +02002445 /* Try to determine the length of the argument. 32 is arbitrary. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002446 buf_size = PyObject_LengthHint(iterable_of_ints, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002447 if (buf_size == -1) {
2448 Py_DECREF(it);
2449 return NULL;
2450 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002451
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002452 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002453 if (bytearray_obj == NULL) {
2454 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002455 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002456 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002457 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002458
2459 while ((item = PyIter_Next(it)) != NULL) {
2460 if (! _getbytevalue(item, &value)) {
2461 Py_DECREF(item);
2462 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002463 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002464 return NULL;
2465 }
2466 buf[len++] = value;
2467 Py_DECREF(item);
2468
2469 if (len >= buf_size) {
2470 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002471 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002472 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002473 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002474 return NULL;
2475 }
2476 /* Recompute the `buf' pointer, since the resizing operation may
2477 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002478 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002479 }
2480 }
2481 Py_DECREF(it);
2482
2483 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002484 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2485 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002486 return NULL;
2487 }
2488
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002489 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2490 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002491 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002492 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002493 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002494
2495 Py_RETURN_NONE;
2496}
2497
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002498/*[clinic input]
2499bytearray.pop
2500
2501 self: self(type="PyByteArrayObject *")
2502 index: Py_ssize_t = -1
2503 The index from where to remove the item.
2504 -1 (the default value) means remove the last item.
2505 /
2506
2507Remove and return a single item from B.
2508
2509If no index argument is given, will pop the last item.
2510[clinic start generated code]*/
2511
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002512static PyObject *
2513bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002514/*[clinic end generated code: output=e0ccd401f8021da8 input=0797e6c0ca9d5a85]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002515{
2516 int value;
2517 Py_ssize_t n = Py_SIZE(self);
2518 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002519
2520 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002521 PyErr_SetString(PyExc_IndexError,
2522 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002523 return NULL;
2524 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002525 if (index < 0)
2526 index += Py_SIZE(self);
2527 if (index < 0 || index >= Py_SIZE(self)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002528 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2529 return NULL;
2530 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002531 if (!_canresize(self))
2532 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002533
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002534 buf = PyByteArray_AS_STRING(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002535 value = buf[index];
2536 memmove(buf + index, buf + index + 1, n - index);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002537 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2538 return NULL;
2539
Mark Dickinson54a3db92009-09-06 10:19:23 +00002540 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002541}
2542
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002543/*[clinic input]
2544bytearray.remove
2545
2546 self: self(type="PyByteArrayObject *")
2547 value: bytesvalue
2548 The value to remove.
2549 /
2550
2551Remove the first occurrence of a value in the bytearray.
2552[clinic start generated code]*/
2553
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002554static PyObject *
2555bytearray_remove_impl(PyByteArrayObject *self, int value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002556/*[clinic end generated code: output=d659e37866709c13 input=47560b11fd856c24]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002557{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002558 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002559 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002560
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002561 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002562 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002563 break;
2564 }
2565 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002566 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002567 return NULL;
2568 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002569 if (!_canresize(self))
2570 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002571
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002572 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002573 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2574 return NULL;
2575
2576 Py_RETURN_NONE;
2577}
2578
2579/* XXX These two helpers could be optimized if argsize == 1 */
2580
2581static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002582lstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002583 void *argptr, Py_ssize_t argsize)
2584{
2585 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002586 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002587 i++;
2588 return i;
2589}
2590
2591static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002592rstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002593 void *argptr, Py_ssize_t argsize)
2594{
2595 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002596 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002597 i--;
2598 return i + 1;
2599}
2600
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002601/*[clinic input]
2602bytearray.strip
2603
2604 bytes: object = None
2605 /
2606
2607Strip leading and trailing bytes contained in the argument.
2608
2609If the argument is omitted or None, strip leading and trailing ASCII whitespace.
2610[clinic start generated code]*/
2611
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002612static PyObject *
2613bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002614/*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002615{
2616 Py_ssize_t left, right, mysize, byteslen;
2617 char *myptr, *bytesptr;
2618 Py_buffer vbytes;
2619
2620 if (bytes == Py_None) {
2621 bytesptr = "\t\n\r\f\v ";
2622 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002623 }
2624 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002625 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002626 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002627 bytesptr = (char *) vbytes.buf;
2628 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002629 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002630 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002631 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002632 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002633 if (left == mysize)
2634 right = left;
2635 else
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002636 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
2637 if (bytes != Py_None)
2638 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002639 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002640}
2641
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002642/*[clinic input]
2643bytearray.lstrip
2644
2645 bytes: object = None
2646 /
2647
2648Strip leading bytes contained in the argument.
2649
2650If the argument is omitted or None, strip leading ASCII whitespace.
2651[clinic start generated code]*/
2652
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002653static PyObject *
2654bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002655/*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002656{
2657 Py_ssize_t left, right, mysize, byteslen;
2658 char *myptr, *bytesptr;
2659 Py_buffer vbytes;
2660
2661 if (bytes == Py_None) {
2662 bytesptr = "\t\n\r\f\v ";
2663 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002664 }
2665 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002666 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002667 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002668 bytesptr = (char *) vbytes.buf;
2669 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002670 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002671 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002672 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002673 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002674 right = mysize;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002675 if (bytes != Py_None)
2676 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002677 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002678}
2679
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002680/*[clinic input]
2681bytearray.rstrip
2682
2683 bytes: object = None
2684 /
2685
2686Strip trailing bytes contained in the argument.
2687
2688If the argument is omitted or None, strip trailing ASCII whitespace.
2689[clinic start generated code]*/
2690
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002691static PyObject *
2692bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002693/*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002694{
2695 Py_ssize_t right, mysize, byteslen;
2696 char *myptr, *bytesptr;
2697 Py_buffer vbytes;
2698
2699 if (bytes == Py_None) {
2700 bytesptr = "\t\n\r\f\v ";
2701 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002702 }
2703 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002704 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002705 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002706 bytesptr = (char *) vbytes.buf;
2707 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002708 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002709 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002710 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002711 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
2712 if (bytes != Py_None)
2713 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002714 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002715}
2716
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002717/*[clinic input]
2718bytearray.decode
2719
2720 encoding: str(c_default="NULL") = 'utf-8'
2721 The encoding with which to decode the bytearray.
2722 errors: str(c_default="NULL") = 'strict'
2723 The error handling scheme to use for the handling of decoding errors.
2724 The default is 'strict' meaning that decoding errors raise a
2725 UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
2726 as well as any other name registered with codecs.register_error that
2727 can handle UnicodeDecodeErrors.
2728
2729Decode the bytearray using the codec registered for encoding.
2730[clinic start generated code]*/
2731
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002732static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002733bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
2734 const char *errors)
2735/*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002736{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002737 if (encoding == NULL)
2738 encoding = PyUnicode_GetDefaultEncoding();
Martin v. Löwis0efea322014-07-27 17:29:17 +02002739 return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002740}
2741
2742PyDoc_STRVAR(alloc_doc,
2743"B.__alloc__() -> int\n\
2744\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002745Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002746
2747static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002748bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002749{
2750 return PyLong_FromSsize_t(self->ob_alloc);
2751}
2752
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002753/*[clinic input]
2754bytearray.join
2755
2756 iterable_of_bytes: object
2757 /
2758
2759Concatenate any number of bytes/bytearray objects.
2760
2761The bytearray whose method is called is inserted in between each pair.
2762
2763The result is returned as a new bytearray object.
2764[clinic start generated code]*/
2765
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002766static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002767bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002768/*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002769{
Martin v. Löwis0efea322014-07-27 17:29:17 +02002770 return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002771}
2772
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002773/*[clinic input]
2774bytearray.splitlines
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002775
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002776 keepends: int(py_default="False") = 0
2777
2778Return a list of the lines in the bytearray, breaking at line boundaries.
2779
2780Line breaks are not included in the resulting list unless keepends is given and
2781true.
2782[clinic start generated code]*/
2783
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002784static PyObject *
2785bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002786/*[clinic end generated code: output=4223c94b895f6ad9 input=36f0b25bc792f6c0]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002787{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002788 return stringlib_splitlines(
2789 (PyObject*) self, PyByteArray_AS_STRING(self),
2790 PyByteArray_GET_SIZE(self), keepends
2791 );
2792}
2793
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002794static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002795hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002796{
2797 if (c >= 128)
2798 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002799 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002800 return c - '0';
2801 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002802 if (Py_ISUPPER(c))
2803 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002804 if (c >= 'a' && c <= 'f')
2805 return c - 'a' + 10;
2806 }
2807 return -1;
2808}
2809
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002810/*[clinic input]
2811@classmethod
2812bytearray.fromhex
2813
2814 cls: self(type="PyObject*")
2815 string: unicode
2816 /
2817
2818Create a bytearray object from a string of hexadecimal numbers.
2819
2820Spaces between two numbers are accepted.
2821Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
2822[clinic start generated code]*/
2823
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002824static PyObject *
2825bytearray_fromhex_impl(PyObject*cls, PyObject *string)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002826/*[clinic end generated code: output=df3da60129b3700c input=907bbd2d34d9367a]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002827{
2828 PyObject *newbytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002829 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002830 Py_ssize_t hexlen, byteslen, i, j;
2831 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002832 void *data;
2833 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002834
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002835 assert(PyUnicode_Check(string));
2836 if (PyUnicode_READY(string))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002837 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002838 kind = PyUnicode_KIND(string);
2839 data = PyUnicode_DATA(string);
2840 hexlen = PyUnicode_GET_LENGTH(string);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002841
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002842 byteslen = hexlen/2; /* This overestimates if there are spaces */
2843 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2844 if (!newbytes)
2845 return NULL;
2846 buf = PyByteArray_AS_STRING(newbytes);
2847 for (i = j = 0; i < hexlen; i += 2) {
2848 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002849 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002850 i++;
2851 if (i >= hexlen)
2852 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002853 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2854 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002855 if (top == -1 || bot == -1) {
2856 PyErr_Format(PyExc_ValueError,
2857 "non-hexadecimal number found in "
2858 "fromhex() arg at position %zd", i);
2859 goto error;
2860 }
2861 buf[j++] = (top << 4) + bot;
2862 }
2863 if (PyByteArray_Resize(newbytes, j) < 0)
2864 goto error;
2865 return newbytes;
2866
2867 error:
2868 Py_DECREF(newbytes);
2869 return NULL;
2870}
2871
Gregory P. Smith8cb65692015-04-25 23:22:26 +00002872PyDoc_STRVAR(hex__doc__,
2873"B.hex() -> string\n\
2874\n\
2875Create a string of hexadecimal numbers from a bytearray object.\n\
2876Example: bytearray([0xb9, 0x01, 0xef]).hex() -> 'b901ef'.");
2877
2878static PyObject *
2879bytearray_hex(PyBytesObject *self)
2880{
2881 char* argbuf = PyByteArray_AS_STRING(self);
2882 Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
2883 return _Py_strhex(argbuf, arglen);
2884}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002885
2886static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002887_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002888{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002889 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002890 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002891 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002892
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002893 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002894 if (dict == NULL) {
2895 PyErr_Clear();
2896 dict = Py_None;
2897 Py_INCREF(dict);
2898 }
2899
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002900 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002901 if (proto < 3) {
2902 /* use str based reduction for backwards compatibility with Python 2.x */
2903 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002904 if (Py_SIZE(self))
2905 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002906 else
2907 latin1 = PyUnicode_FromString("");
2908 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2909 }
2910 else {
2911 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002912 if (Py_SIZE(self)) {
2913 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002914 }
2915 else {
2916 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2917 }
2918 }
2919}
2920
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002921/*[clinic input]
2922bytearray.__reduce__ as bytearray_reduce
2923
2924 self: self(type="PyByteArrayObject *")
2925
2926Return state information for pickling.
2927[clinic start generated code]*/
2928
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002929static PyObject *
2930bytearray_reduce_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002931/*[clinic end generated code: output=52bf304086464cab input=fbb07de4d102a03a]*/
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002932{
2933 return _common_reduce(self, 2);
2934}
2935
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002936/*[clinic input]
2937bytearray.__reduce_ex__ as bytearray_reduce_ex
2938
2939 self: self(type="PyByteArrayObject *")
2940 proto: int = 0
2941 /
2942
2943Return state information for pickling.
2944[clinic start generated code]*/
2945
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002946static PyObject *
2947bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002948/*[clinic end generated code: output=52eac33377197520 input=0e091a42ca6dbd91]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002949{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002950 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002951}
2952
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002953/*[clinic input]
2954bytearray.__sizeof__ as bytearray_sizeof
2955
2956 self: self(type="PyByteArrayObject *")
2957
2958Returns the size of the bytearray object in memory, in bytes.
2959[clinic start generated code]*/
2960
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002961static PyObject *
2962bytearray_sizeof_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002963/*[clinic end generated code: output=738abdd17951c427 input=6b23d305362b462b]*/
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002964{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002965 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002966
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002967 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2968 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002969}
2970
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002971static PySequenceMethods bytearray_as_sequence = {
2972 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002973 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002974 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2975 (ssizeargfunc)bytearray_getitem, /* sq_item */
2976 0, /* sq_slice */
2977 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2978 0, /* sq_ass_slice */
2979 (objobjproc)bytearray_contains, /* sq_contains */
2980 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2981 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002982};
2983
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002984static PyMappingMethods bytearray_as_mapping = {
2985 (lenfunc)bytearray_length,
2986 (binaryfunc)bytearray_subscript,
2987 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002988};
2989
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002990static PyBufferProcs bytearray_as_buffer = {
2991 (getbufferproc)bytearray_getbuffer,
2992 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002993};
2994
2995static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002996bytearray_methods[] = {
2997 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002998 BYTEARRAY_REDUCE_METHODDEF
2999 BYTEARRAY_REDUCE_EX_METHODDEF
3000 BYTEARRAY_SIZEOF_METHODDEF
3001 BYTEARRAY_APPEND_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003002 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
3003 _Py_capitalize__doc__},
3004 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003005 BYTEARRAY_CLEAR_METHODDEF
3006 BYTEARRAY_COPY_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003007 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003008 BYTEARRAY_DECODE_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003009 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Ezio Melotti745d54d2013-11-16 19:10:57 +02003010 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003011 expandtabs__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003012 BYTEARRAY_EXTEND_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003013 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003014 BYTEARRAY_FROMHEX_METHODDEF
Gregory P. Smith8cb65692015-04-25 23:22:26 +00003015 {"hex", (PyCFunction)bytearray_hex, METH_NOARGS, hex__doc__},
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003016 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003017 BYTEARRAY_INSERT_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003018 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
3019 _Py_isalnum__doc__},
3020 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
3021 _Py_isalpha__doc__},
3022 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
3023 _Py_isdigit__doc__},
3024 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
3025 _Py_islower__doc__},
3026 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
3027 _Py_isspace__doc__},
3028 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
3029 _Py_istitle__doc__},
3030 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
3031 _Py_isupper__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003032 BYTEARRAY_JOIN_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003033 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
3034 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003035 BYTEARRAY_LSTRIP_METHODDEF
3036 BYTEARRAY_MAKETRANS_METHODDEF
3037 BYTEARRAY_PARTITION_METHODDEF
3038 BYTEARRAY_POP_METHODDEF
3039 BYTEARRAY_REMOVE_METHODDEF
3040 BYTEARRAY_REPLACE_METHODDEF
3041 BYTEARRAY_REVERSE_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003042 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
3043 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003044 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003045 BYTEARRAY_RPARTITION_METHODDEF
3046 BYTEARRAY_RSPLIT_METHODDEF
3047 BYTEARRAY_RSTRIP_METHODDEF
3048 BYTEARRAY_SPLIT_METHODDEF
3049 BYTEARRAY_SPLITLINES_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003050 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003051 startswith__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003052 BYTEARRAY_STRIP_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003053 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
3054 _Py_swapcase__doc__},
3055 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003056 BYTEARRAY_TRANSLATE_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003057 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
3058 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
3059 {NULL}
3060};
3061
Ethan Furmanb95b5612015-01-23 20:05:18 -08003062static PyObject *
3063bytearray_mod(PyObject *v, PyObject *w)
3064{
3065 if (!PyByteArray_Check(v))
3066 Py_RETURN_NOTIMPLEMENTED;
3067 return bytearray_format((PyByteArrayObject *)v, w);
3068}
3069
3070static PyNumberMethods bytearray_as_number = {
3071 0, /*nb_add*/
3072 0, /*nb_subtract*/
3073 0, /*nb_multiply*/
3074 bytearray_mod, /*nb_remainder*/
3075};
3076
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003077PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00003078"bytearray(iterable_of_ints) -> bytearray\n\
3079bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003080bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
3081bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
3082bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003083\n\
3084Construct an mutable bytearray object from:\n\
3085 - an iterable yielding integers in range(256)\n\
3086 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003087 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003088 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003089 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003090
3091
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003092static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003093
3094PyTypeObject PyByteArray_Type = {
3095 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3096 "bytearray",
3097 sizeof(PyByteArrayObject),
3098 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003099 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003100 0, /* tp_print */
3101 0, /* tp_getattr */
3102 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003103 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003104 (reprfunc)bytearray_repr, /* tp_repr */
Ethan Furmanb95b5612015-01-23 20:05:18 -08003105 &bytearray_as_number, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003106 &bytearray_as_sequence, /* tp_as_sequence */
3107 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003108 0, /* tp_hash */
3109 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003110 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003111 PyObject_GenericGetAttr, /* tp_getattro */
3112 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003113 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003114 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003115 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003116 0, /* tp_traverse */
3117 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003118 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003119 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003120 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003121 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003122 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003123 0, /* tp_members */
3124 0, /* tp_getset */
3125 0, /* tp_base */
3126 0, /* tp_dict */
3127 0, /* tp_descr_get */
3128 0, /* tp_descr_set */
3129 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003130 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003131 PyType_GenericAlloc, /* tp_alloc */
3132 PyType_GenericNew, /* tp_new */
3133 PyObject_Del, /* tp_free */
3134};
3135
3136/*********************** Bytes Iterator ****************************/
3137
3138typedef struct {
3139 PyObject_HEAD
3140 Py_ssize_t it_index;
3141 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
3142} bytesiterobject;
3143
3144static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003145bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003146{
3147 _PyObject_GC_UNTRACK(it);
3148 Py_XDECREF(it->it_seq);
3149 PyObject_GC_Del(it);
3150}
3151
3152static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003153bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003154{
3155 Py_VISIT(it->it_seq);
3156 return 0;
3157}
3158
3159static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003160bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003161{
3162 PyByteArrayObject *seq;
3163 PyObject *item;
3164
3165 assert(it != NULL);
3166 seq = it->it_seq;
3167 if (seq == NULL)
3168 return NULL;
3169 assert(PyByteArray_Check(seq));
3170
3171 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
3172 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003173 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003174 if (item != NULL)
3175 ++it->it_index;
3176 return item;
3177 }
3178
3179 Py_DECREF(seq);
3180 it->it_seq = NULL;
3181 return NULL;
3182}
3183
3184static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003185bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003186{
3187 Py_ssize_t len = 0;
3188 if (it->it_seq)
3189 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3190 return PyLong_FromSsize_t(len);
3191}
3192
3193PyDoc_STRVAR(length_hint_doc,
3194 "Private method returning an estimate of len(list(it)).");
3195
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003196static PyObject *
3197bytearrayiter_reduce(bytesiterobject *it)
3198{
3199 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02003200 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003201 it->it_seq, it->it_index);
3202 } else {
3203 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
3204 if (u == NULL)
3205 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02003206 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003207 }
3208}
3209
3210static PyObject *
3211bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3212{
3213 Py_ssize_t index = PyLong_AsSsize_t(state);
3214 if (index == -1 && PyErr_Occurred())
3215 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +00003216 if (it->it_seq != NULL) {
3217 if (index < 0)
3218 index = 0;
3219 else if (index > PyByteArray_GET_SIZE(it->it_seq))
3220 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
3221 it->it_index = index;
3222 }
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003223 Py_RETURN_NONE;
3224}
3225
3226PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3227
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003228static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003229 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003230 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003231 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003232 bytearray_reduce__doc__},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003233 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3234 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003235 {NULL, NULL} /* sentinel */
3236};
3237
3238PyTypeObject PyByteArrayIter_Type = {
3239 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3240 "bytearray_iterator", /* tp_name */
3241 sizeof(bytesiterobject), /* tp_basicsize */
3242 0, /* tp_itemsize */
3243 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003244 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003245 0, /* tp_print */
3246 0, /* tp_getattr */
3247 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003248 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003249 0, /* tp_repr */
3250 0, /* tp_as_number */
3251 0, /* tp_as_sequence */
3252 0, /* tp_as_mapping */
3253 0, /* tp_hash */
3254 0, /* tp_call */
3255 0, /* tp_str */
3256 PyObject_GenericGetAttr, /* tp_getattro */
3257 0, /* tp_setattro */
3258 0, /* tp_as_buffer */
3259 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3260 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003261 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003262 0, /* tp_clear */
3263 0, /* tp_richcompare */
3264 0, /* tp_weaklistoffset */
3265 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003266 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3267 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003268 0,
3269};
3270
3271static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003272bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003273{
3274 bytesiterobject *it;
3275
3276 if (!PyByteArray_Check(seq)) {
3277 PyErr_BadInternalCall();
3278 return NULL;
3279 }
3280 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3281 if (it == NULL)
3282 return NULL;
3283 it->it_index = 0;
3284 Py_INCREF(seq);
3285 it->it_seq = (PyByteArrayObject *)seq;
3286 _PyObject_GC_TRACK(it);
3287 return (PyObject *)it;
3288}