blob: 8b3267e745088fd25f42d27b75bb8eebb58abf34 [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"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00008
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02009/*[clinic input]
10class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
11[clinic start generated code]*/
12/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/
13
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000014char _PyByteArray_empty_string[] = "";
Christian Heimes2c9c7a52008-05-26 13:42:13 +000015
16void
17PyByteArray_Fini(void)
18{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000019}
20
21int
22PyByteArray_Init(void)
23{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000024 return 1;
25}
26
27/* end nullbytes support */
28
29/* Helpers */
30
31static int
32_getbytevalue(PyObject* arg, int *value)
33{
34 long face_value;
35
36 if (PyLong_Check(arg)) {
37 face_value = PyLong_AsLong(arg);
Georg Brandl9a54d7c2008-07-16 23:15:30 +000038 } else {
39 PyObject *index = PyNumber_Index(arg);
40 if (index == NULL) {
41 PyErr_Format(PyExc_TypeError, "an integer is required");
Mark Dickinson10de93a2010-07-09 19:25:48 +000042 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000043 return 0;
44 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +000045 face_value = PyLong_AsLong(index);
46 Py_DECREF(index);
47 }
48
49 if (face_value < 0 || face_value >= 256) {
50 /* this includes the OverflowError in case the long is too large */
51 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Mark Dickinson10de93a2010-07-09 19:25:48 +000052 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000053 return 0;
54 }
55
56 *value = face_value;
57 return 1;
58}
59
60static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +000061bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000062{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000063 void *ptr;
64 if (view == NULL) {
Stefan Krah5178d912015-02-03 16:57:21 +010065 PyErr_SetString(PyExc_BufferError,
66 "bytearray_getbuffer: view==NULL argument is obsolete");
67 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000068 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000069 ptr = (void *) PyByteArray_AS_STRING(obj);
Stefan Krah5178d912015-02-03 16:57:21 +010070 /* cannot fail if view != NULL and readonly == 0 */
71 (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
72 obj->ob_exports++;
73 return 0;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000074}
75
76static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +000077bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000078{
79 obj->ob_exports--;
80}
81
Antoine Pitrou5504e892008-12-06 21:27:53 +000082static int
83_canresize(PyByteArrayObject *self)
84{
85 if (self->ob_exports > 0) {
86 PyErr_SetString(PyExc_BufferError,
87 "Existing exports of data: object cannot be re-sized");
88 return 0;
89 }
90 return 1;
91}
92
Christian Heimes2c9c7a52008-05-26 13:42:13 +000093/* Direct API functions */
94
95PyObject *
96PyByteArray_FromObject(PyObject *input)
97{
98 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
99 input, NULL);
100}
101
102PyObject *
103PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
104{
105 PyByteArrayObject *new;
106 Py_ssize_t alloc;
107
108 if (size < 0) {
109 PyErr_SetString(PyExc_SystemError,
110 "Negative size passed to PyByteArray_FromStringAndSize");
111 return NULL;
112 }
113
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000114 /* Prevent buffer overflow when setting alloc to size+1. */
115 if (size == PY_SSIZE_T_MAX) {
116 return PyErr_NoMemory();
117 }
118
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000119 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
120 if (new == NULL)
121 return NULL;
122
123 if (size == 0) {
124 new->ob_bytes = NULL;
125 alloc = 0;
126 }
127 else {
128 alloc = size + 1;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100129 new->ob_bytes = PyObject_Malloc(alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000130 if (new->ob_bytes == NULL) {
131 Py_DECREF(new);
132 return PyErr_NoMemory();
133 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +0000134 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000135 memcpy(new->ob_bytes, bytes, size);
136 new->ob_bytes[size] = '\0'; /* Trailing null byte */
137 }
138 Py_SIZE(new) = size;
139 new->ob_alloc = alloc;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200140 new->ob_start = new->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000141 new->ob_exports = 0;
142
143 return (PyObject *)new;
144}
145
146Py_ssize_t
147PyByteArray_Size(PyObject *self)
148{
149 assert(self != NULL);
150 assert(PyByteArray_Check(self));
151
152 return PyByteArray_GET_SIZE(self);
153}
154
155char *
156PyByteArray_AsString(PyObject *self)
157{
158 assert(self != NULL);
159 assert(PyByteArray_Check(self));
160
161 return PyByteArray_AS_STRING(self);
162}
163
164int
Antoine Pitroucc231542014-11-02 18:40:09 +0100165PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000166{
167 void *sval;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200168 PyByteArrayObject *obj = ((PyByteArrayObject *)self);
Antoine Pitroucc231542014-11-02 18:40:09 +0100169 /* All computations are done unsigned to avoid integer overflows
170 (see issue #22335). */
171 size_t alloc = (size_t) obj->ob_alloc;
172 size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
173 size_t size = (size_t) requested_size;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000174
175 assert(self != NULL);
176 assert(PyByteArray_Check(self));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200177 assert(logical_offset <= alloc);
Antoine Pitroucc231542014-11-02 18:40:09 +0100178 assert(requested_size >= 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000179
Antoine Pitroucc231542014-11-02 18:40:09 +0100180 if (requested_size == Py_SIZE(self)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000181 return 0;
182 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200183 if (!_canresize(obj)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000184 return -1;
185 }
186
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200187 if (size + logical_offset + 1 < alloc) {
188 /* Current buffer is large enough to host the requested size,
189 decide on a strategy. */
190 if (size < alloc / 2) {
191 /* Major downsize; resize down to exact size */
192 alloc = size + 1;
193 }
194 else {
195 /* Minor downsize; quick exit */
196 Py_SIZE(self) = size;
197 PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
198 return 0;
199 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000200 }
201 else {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200202 /* Need growing, decide on a strategy */
203 if (size <= alloc * 1.125) {
204 /* Moderate upsize; overallocate similar to list_resize() */
205 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
206 }
207 else {
208 /* Major upsize; resize up to exact size */
209 alloc = size + 1;
210 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000211 }
Antoine Pitroucc231542014-11-02 18:40:09 +0100212 if (alloc > PY_SSIZE_T_MAX) {
213 PyErr_NoMemory();
214 return -1;
215 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000216
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200217 if (logical_offset > 0) {
218 sval = PyObject_Malloc(alloc);
219 if (sval == NULL) {
220 PyErr_NoMemory();
221 return -1;
222 }
Antoine Pitroucc231542014-11-02 18:40:09 +0100223 memcpy(sval, PyByteArray_AS_STRING(self),
224 Py_MIN(requested_size, Py_SIZE(self)));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200225 PyObject_Free(obj->ob_bytes);
226 }
227 else {
228 sval = PyObject_Realloc(obj->ob_bytes, alloc);
229 if (sval == NULL) {
230 PyErr_NoMemory();
231 return -1;
232 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000233 }
234
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200235 obj->ob_bytes = obj->ob_start = sval;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000236 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200237 obj->ob_alloc = alloc;
238 obj->ob_bytes[size] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000239
240 return 0;
241}
242
243PyObject *
244PyByteArray_Concat(PyObject *a, PyObject *b)
245{
246 Py_ssize_t size;
247 Py_buffer va, vb;
248 PyByteArrayObject *result = NULL;
249
250 va.len = -1;
251 vb.len = -1;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200252 if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
253 PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000254 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
255 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
256 goto done;
257 }
258
259 size = va.len + vb.len;
260 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000261 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000262 goto done;
263 }
264
265 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
266 if (result != NULL) {
267 memcpy(result->ob_bytes, va.buf, va.len);
268 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
269 }
270
271 done:
272 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000273 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000274 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000275 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000276 return (PyObject *)result;
277}
278
Ethan Furmanb95b5612015-01-23 20:05:18 -0800279static PyObject *
280bytearray_format(PyByteArrayObject *self, PyObject *args)
281{
282 PyObject *bytes_in, *bytes_out, *res;
283 char *bytestring;
284
285 if (self == NULL || !PyByteArray_Check(self) || args == NULL) {
286 PyErr_BadInternalCall();
287 return NULL;
288 }
289 bytestring = PyByteArray_AS_STRING(self);
290 bytes_in = PyBytes_FromString(bytestring);
291 if (bytes_in == NULL)
292 return NULL;
293 bytes_out = _PyBytes_Format(bytes_in, args);
294 Py_DECREF(bytes_in);
295 if (bytes_out == NULL)
296 return NULL;
297 res = PyByteArray_FromObject(bytes_out);
298 Py_DECREF(bytes_out);
299 if (res == NULL)
300 return NULL;
301 return res;
302}
303
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000304/* Functions stuffed into the type object */
305
306static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000307bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000308{
309 return Py_SIZE(self);
310}
311
312static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000313bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000314{
315 Py_ssize_t mysize;
316 Py_ssize_t size;
317 Py_buffer vo;
318
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200319 if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000320 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
321 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
322 return NULL;
323 }
324
325 mysize = Py_SIZE(self);
326 size = mysize + vo.len;
327 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000328 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000329 return PyErr_NoMemory();
330 }
331 if (size < self->ob_alloc) {
332 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200333 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000334 }
335 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000336 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000337 return NULL;
338 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200339 memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000340 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000341 Py_INCREF(self);
342 return (PyObject *)self;
343}
344
345static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000346bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000347{
348 PyByteArrayObject *result;
349 Py_ssize_t mysize;
350 Py_ssize_t size;
351
352 if (count < 0)
353 count = 0;
354 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000355 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000356 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000357 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000358 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
359 if (result != NULL && size != 0) {
360 if (mysize == 1)
361 memset(result->ob_bytes, self->ob_bytes[0], size);
362 else {
363 Py_ssize_t i;
364 for (i = 0; i < count; i++)
365 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
366 }
367 }
368 return (PyObject *)result;
369}
370
371static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000372bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000373{
374 Py_ssize_t mysize;
375 Py_ssize_t size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200376 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000377
378 if (count < 0)
379 count = 0;
380 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000381 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000382 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000383 size = mysize * count;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200384 if (PyByteArray_Resize((PyObject *)self, size) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000385 return NULL;
386
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200387 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000388 if (mysize == 1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200389 memset(buf, buf[0], size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000390 else {
391 Py_ssize_t i;
392 for (i = 1; i < count; i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200393 memcpy(buf + i*mysize, buf, mysize);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000394 }
395
396 Py_INCREF(self);
397 return (PyObject *)self;
398}
399
400static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000401bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000402{
403 if (i < 0)
404 i += Py_SIZE(self);
405 if (i < 0 || i >= Py_SIZE(self)) {
406 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
407 return NULL;
408 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200409 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000410}
411
412static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000413bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000414{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000415 if (PyIndex_Check(index)) {
416 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000417
418 if (i == -1 && PyErr_Occurred())
419 return NULL;
420
421 if (i < 0)
422 i += PyByteArray_GET_SIZE(self);
423
424 if (i < 0 || i >= Py_SIZE(self)) {
425 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
426 return NULL;
427 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200428 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000429 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000430 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000431 Py_ssize_t start, stop, step, slicelength, cur, i;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000432 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000433 PyByteArray_GET_SIZE(self),
434 &start, &stop, &step, &slicelength) < 0) {
435 return NULL;
436 }
437
438 if (slicelength <= 0)
439 return PyByteArray_FromStringAndSize("", 0);
440 else if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200441 return PyByteArray_FromStringAndSize(
442 PyByteArray_AS_STRING(self) + start, slicelength);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000443 }
444 else {
445 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000446 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000447 PyObject *result;
448
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000449 result = PyByteArray_FromStringAndSize(NULL, slicelength);
450 if (result == NULL)
451 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000452
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000453 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000454 for (cur = start, i = 0; i < slicelength;
455 cur += step, i++) {
456 result_buf[i] = source_buf[cur];
457 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000458 return result;
459 }
460 }
461 else {
Terry Jan Reedyffff1442014-08-02 01:30:37 -0400462 PyErr_Format(PyExc_TypeError,
463 "bytearray indices must be integers or slices, not %.200s",
464 Py_TYPE(index)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000465 return NULL;
466 }
467}
468
469static int
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200470bytearray_setslice_linear(PyByteArrayObject *self,
471 Py_ssize_t lo, Py_ssize_t hi,
472 char *bytes, Py_ssize_t bytes_len)
473{
474 Py_ssize_t avail = hi - lo;
475 char *buf = PyByteArray_AS_STRING(self);
476 Py_ssize_t growth = bytes_len - avail;
Victor Stinner84557232013-11-21 12:29:51 +0100477 int res = 0;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200478 assert(avail >= 0);
479
Victor Stinner84557232013-11-21 12:29:51 +0100480 if (growth < 0) {
481 if (!_canresize(self))
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200482 return -1;
Victor Stinner84557232013-11-21 12:29:51 +0100483
484 if (lo == 0) {
485 /* Shrink the buffer by advancing its logical start */
486 self->ob_start -= growth;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200487 /*
Victor Stinner84557232013-11-21 12:29:51 +0100488 0 lo hi old_size
489 | |<----avail----->|<-----tail------>|
490 | |<-bytes_len->|<-----tail------>|
491 0 new_lo new_hi new_size
492 */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200493 }
Victor Stinner84557232013-11-21 12:29:51 +0100494 else {
495 /*
496 0 lo hi old_size
497 | |<----avail----->|<-----tomove------>|
498 | |<-bytes_len->|<-----tomove------>|
499 0 lo new_hi new_size
500 */
501 memmove(buf + lo + bytes_len, buf + hi,
502 Py_SIZE(self) - hi);
503 }
504 if (PyByteArray_Resize((PyObject *)self,
505 Py_SIZE(self) + growth) < 0) {
506 /* Issue #19578: Handling the memory allocation failure here is
507 tricky here because the bytearray object has already been
508 modified. Depending on growth and lo, the behaviour is
509 different.
510
511 If growth < 0 and lo != 0, the operation is completed, but a
512 MemoryError is still raised and the memory block is not
513 shrinked. Otherwise, the bytearray is restored in its previous
514 state and a MemoryError is raised. */
515 if (lo == 0) {
516 self->ob_start += growth;
517 return -1;
518 }
519 /* memmove() removed bytes, the bytearray object cannot be
520 restored in its previous state. */
521 Py_SIZE(self) += growth;
522 res = -1;
523 }
524 buf = PyByteArray_AS_STRING(self);
525 }
526 else if (growth > 0) {
527 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
528 PyErr_NoMemory();
529 return -1;
530 }
531
532 if (PyByteArray_Resize((PyObject *)self,
533 Py_SIZE(self) + growth) < 0) {
534 return -1;
535 }
536 buf = PyByteArray_AS_STRING(self);
537 /* Make the place for the additional bytes */
538 /*
539 0 lo hi old_size
540 | |<-avail->|<-----tomove------>|
541 | |<---bytes_len-->|<-----tomove------>|
542 0 lo new_hi new_size
543 */
544 memmove(buf + lo + bytes_len, buf + hi,
545 Py_SIZE(self) - lo - bytes_len);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200546 }
547
548 if (bytes_len > 0)
549 memcpy(buf + lo, bytes, bytes_len);
Victor Stinner84557232013-11-21 12:29:51 +0100550 return res;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200551}
552
553static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000554bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000555 PyObject *values)
556{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200557 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000558 void *bytes;
559 Py_buffer vbytes;
560 int res = 0;
561
562 vbytes.len = -1;
563 if (values == (PyObject *)self) {
564 /* Make a copy and call this function recursively */
565 int err;
566 values = PyByteArray_FromObject(values);
567 if (values == NULL)
568 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000569 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000570 Py_DECREF(values);
571 return err;
572 }
573 if (values == NULL) {
574 /* del b[lo:hi] */
575 bytes = NULL;
576 needed = 0;
577 }
578 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200579 if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
580 PyErr_Format(PyExc_TypeError,
581 "can't set bytearray slice from %.100s",
582 Py_TYPE(values)->tp_name);
583 return -1;
584 }
585 needed = vbytes.len;
586 bytes = vbytes.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000587 }
588
589 if (lo < 0)
590 lo = 0;
591 if (hi < lo)
592 hi = lo;
593 if (hi > Py_SIZE(self))
594 hi = Py_SIZE(self);
595
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200596 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000597 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200598 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000599 return res;
600}
601
602static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000603bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000604{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000605 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000606
607 if (i < 0)
608 i += Py_SIZE(self);
609
610 if (i < 0 || i >= Py_SIZE(self)) {
611 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
612 return -1;
613 }
614
615 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000616 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000617
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000618 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000619 return -1;
620
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200621 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000622 return 0;
623}
624
625static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000626bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000627{
628 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200629 char *buf, *bytes;
630 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000631
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000632 if (PyIndex_Check(index)) {
633 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000634
635 if (i == -1 && PyErr_Occurred())
636 return -1;
637
638 if (i < 0)
639 i += PyByteArray_GET_SIZE(self);
640
641 if (i < 0 || i >= Py_SIZE(self)) {
642 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
643 return -1;
644 }
645
646 if (values == NULL) {
647 /* Fall through to slice assignment */
648 start = i;
649 stop = i + 1;
650 step = 1;
651 slicelen = 1;
652 }
653 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000654 int ival;
655 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000656 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200657 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000658 return 0;
659 }
660 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000661 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000662 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000663 PyByteArray_GET_SIZE(self),
664 &start, &stop, &step, &slicelen) < 0) {
665 return -1;
666 }
667 }
668 else {
Terry Jan Reedyffff1442014-08-02 01:30:37 -0400669 PyErr_Format(PyExc_TypeError,
670 "bytearray indices must be integers or slices, not %.200s",
671 Py_TYPE(index)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000672 return -1;
673 }
674
675 if (values == NULL) {
676 bytes = NULL;
677 needed = 0;
678 }
679 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100680 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200681 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
682 PyErr_SetString(PyExc_TypeError,
683 "can assign only bytes, buffers, or iterables "
684 "of ints in range(0, 256)");
685 return -1;
686 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000687 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000688 values = PyByteArray_FromObject(values);
689 if (values == NULL)
690 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000691 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000692 Py_DECREF(values);
693 return err;
694 }
695 else {
696 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200697 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000698 needed = Py_SIZE(values);
699 }
700 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
701 if ((step < 0 && start < stop) ||
702 (step > 0 && start > stop))
703 stop = start;
704 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200705 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000706 }
707 else {
708 if (needed == 0) {
709 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000710 size_t cur;
711 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000712
Antoine Pitrou5504e892008-12-06 21:27:53 +0000713 if (!_canresize(self))
714 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000715
716 if (slicelen == 0)
717 /* Nothing to do here. */
718 return 0;
719
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000720 if (step < 0) {
721 stop = start + 1;
722 start = stop + step * (slicelen - 1) - 1;
723 step = -step;
724 }
725 for (cur = start, i = 0;
726 i < slicelen; cur += step, i++) {
727 Py_ssize_t lim = step - 1;
728
Mark Dickinson66f575b2010-02-14 12:53:32 +0000729 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000730 lim = PyByteArray_GET_SIZE(self) - cur - 1;
731
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200732 memmove(buf + cur - i,
733 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000734 }
735 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000736 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000737 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200738 memmove(buf + cur - slicelen,
739 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000740 PyByteArray_GET_SIZE(self) - cur);
741 }
742 if (PyByteArray_Resize((PyObject *)self,
743 PyByteArray_GET_SIZE(self) - slicelen) < 0)
744 return -1;
745
746 return 0;
747 }
748 else {
749 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000750 Py_ssize_t i;
751 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000752
753 if (needed != slicelen) {
754 PyErr_Format(PyExc_ValueError,
755 "attempt to assign bytes of size %zd "
756 "to extended slice of size %zd",
757 needed, slicelen);
758 return -1;
759 }
760 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200761 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000762 return 0;
763 }
764 }
765}
766
767static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000768bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000769{
770 static char *kwlist[] = {"source", "encoding", "errors", 0};
771 PyObject *arg = NULL;
772 const char *encoding = NULL;
773 const char *errors = NULL;
774 Py_ssize_t count;
775 PyObject *it;
776 PyObject *(*iternext)(PyObject *);
777
778 if (Py_SIZE(self) != 0) {
779 /* Empty previous contents (yes, do this first of all!) */
780 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
781 return -1;
782 }
783
784 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000785 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000786 &arg, &encoding, &errors))
787 return -1;
788
789 /* Make a quick exit if no first argument */
790 if (arg == NULL) {
791 if (encoding != NULL || errors != NULL) {
792 PyErr_SetString(PyExc_TypeError,
793 "encoding or errors without sequence argument");
794 return -1;
795 }
796 return 0;
797 }
798
799 if (PyUnicode_Check(arg)) {
800 /* Encode via the codec registry */
801 PyObject *encoded, *new;
802 if (encoding == NULL) {
803 PyErr_SetString(PyExc_TypeError,
804 "string argument without an encoding");
805 return -1;
806 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000807 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000808 if (encoded == NULL)
809 return -1;
810 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000811 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000812 Py_DECREF(encoded);
813 if (new == NULL)
814 return -1;
815 Py_DECREF(new);
816 return 0;
817 }
818
819 /* If it's not unicode, there can't be encoding or errors */
820 if (encoding != NULL || errors != NULL) {
821 PyErr_SetString(PyExc_TypeError,
822 "encoding or errors without a string argument");
823 return -1;
824 }
825
826 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000827 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
828 if (count == -1 && PyErr_Occurred()) {
829 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000830 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000831 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000832 }
833 else if (count < 0) {
834 PyErr_SetString(PyExc_ValueError, "negative count");
835 return -1;
836 }
837 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000838 if (count > 0) {
Victor Stinner2bc4d952014-06-02 22:22:42 +0200839 if (PyByteArray_Resize((PyObject *)self, count))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000840 return -1;
Victor Stinner2bc4d952014-06-02 22:22:42 +0200841 memset(PyByteArray_AS_STRING(self), 0, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000842 }
843 return 0;
844 }
845
846 /* Use the buffer API */
847 if (PyObject_CheckBuffer(arg)) {
848 Py_ssize_t size;
849 Py_buffer view;
850 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
851 return -1;
852 size = view.len;
853 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200854 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
855 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200856 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000857 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000858 return 0;
859 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000860 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000861 return -1;
862 }
863
864 /* XXX Optimize this if the arguments is a list, tuple */
865
866 /* Get the iterator */
867 it = PyObject_GetIter(arg);
868 if (it == NULL)
869 return -1;
870 iternext = *Py_TYPE(it)->tp_iternext;
871
872 /* Run the iterator to exhaustion */
873 for (;;) {
874 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000875 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000876
877 /* Get the next item */
878 item = iternext(it);
879 if (item == NULL) {
880 if (PyErr_Occurred()) {
881 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
882 goto error;
883 PyErr_Clear();
884 }
885 break;
886 }
887
888 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000889 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000890 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000891 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000892 goto error;
893
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000894 /* Append the byte */
895 if (Py_SIZE(self) < self->ob_alloc)
896 Py_SIZE(self)++;
897 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
898 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200899 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000900 }
901
902 /* Clean up and return success */
903 Py_DECREF(it);
904 return 0;
905
906 error:
907 /* Error handling when it != NULL */
908 Py_DECREF(it);
909 return -1;
910}
911
912/* Mostly copied from string_repr, but without the
913 "smart quote" functionality. */
914static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000915bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000916{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000917 const char *quote_prefix = "bytearray(b";
918 const char *quote_postfix = ")";
919 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200920 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000921 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000922 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200923 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200924 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200925 char c;
926 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200927 int quote;
928 char *test, *start;
929 char *buffer;
930
931 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000932 PyErr_SetString(PyExc_OverflowError,
933 "bytearray object is too large to make repr");
934 return NULL;
935 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200936
937 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100938 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200939 if (buffer == NULL) {
940 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000941 return NULL;
942 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000943
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200944 /* Figure out which quote to use; single is preferred */
945 quote = '\'';
946 start = PyByteArray_AS_STRING(self);
947 for (test = start; test < start+length; ++test) {
948 if (*test == '"') {
949 quote = '\''; /* back to single */
950 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000951 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200952 else if (*test == '\'')
953 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000954 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200955
956 p = buffer;
957 while (*quote_prefix)
958 *p++ = *quote_prefix++;
959 *p++ = quote;
960
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200961 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200962 for (i = 0; i < length; i++) {
963 /* There's at least enough room for a hex escape
964 and a closing quote. */
965 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200966 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200967 if (c == '\'' || c == '\\')
968 *p++ = '\\', *p++ = c;
969 else if (c == '\t')
970 *p++ = '\\', *p++ = 't';
971 else if (c == '\n')
972 *p++ = '\\', *p++ = 'n';
973 else if (c == '\r')
974 *p++ = '\\', *p++ = 'r';
975 else if (c == 0)
976 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
977 else if (c < ' ' || c >= 0x7f) {
978 *p++ = '\\';
979 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200980 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
981 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200982 }
983 else
984 *p++ = c;
985 }
986 assert(newsize - (p - buffer) >= 1);
987 *p++ = quote;
988 while (*quote_postfix) {
989 *p++ = *quote_postfix++;
990 }
991
992 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100993 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200994 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000995}
996
997static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000998bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000999{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001000 if (Py_BytesWarningFlag) {
1001 if (PyErr_WarnEx(PyExc_BytesWarning,
1002 "str() on a bytearray instance", 1))
1003 return NULL;
1004 }
1005 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001006}
1007
1008static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001009bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001010{
1011 Py_ssize_t self_size, other_size;
1012 Py_buffer self_bytes, other_bytes;
1013 PyObject *res;
1014 Py_ssize_t minsize;
1015 int cmp;
1016
1017 /* Bytes can be compared to anything that supports the (binary)
1018 buffer API. Except that a comparison with Unicode is always an
1019 error, even if the comparison is for equality. */
1020 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1021 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +00001022 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001023 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +00001024 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001025 return NULL;
1026 }
1027
Brian Curtindfc80e32011-08-10 20:28:54 -05001028 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001029 }
1030
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001031 if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001032 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -05001033 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001034 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001035 self_size = self_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001036
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001037 if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001038 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001039 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001040 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001041 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001042 other_size = other_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001043
1044 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1045 /* Shortcut: if the lengths differ, the objects differ */
1046 cmp = (op == Py_NE);
1047 }
1048 else {
1049 minsize = self_size;
1050 if (other_size < minsize)
1051 minsize = other_size;
1052
1053 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1054 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1055
1056 if (cmp == 0) {
1057 if (self_size < other_size)
1058 cmp = -1;
1059 else if (self_size > other_size)
1060 cmp = 1;
1061 }
1062
1063 switch (op) {
1064 case Py_LT: cmp = cmp < 0; break;
1065 case Py_LE: cmp = cmp <= 0; break;
1066 case Py_EQ: cmp = cmp == 0; break;
1067 case Py_NE: cmp = cmp != 0; break;
1068 case Py_GT: cmp = cmp > 0; break;
1069 case Py_GE: cmp = cmp >= 0; break;
1070 }
1071 }
1072
1073 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001074 PyBuffer_Release(&self_bytes);
1075 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001076 Py_INCREF(res);
1077 return res;
1078}
1079
1080static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001081bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001082{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001083 if (self->ob_exports > 0) {
1084 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001085 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001086 PyErr_Print();
1087 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001088 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001089 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001090 }
1091 Py_TYPE(self)->tp_free((PyObject *)self);
1092}
1093
1094
1095/* -------------------------------------------------------------------- */
1096/* Methods */
1097
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001098#define FASTSEARCH fastsearch
1099#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001100#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001101#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001102#define STRINGLIB_LEN PyByteArray_GET_SIZE
1103#define STRINGLIB_STR PyByteArray_AS_STRING
1104#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001105#define STRINGLIB_ISSPACE Py_ISSPACE
1106#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001107#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1108#define STRINGLIB_MUTABLE 1
1109
1110#include "stringlib/fastsearch.h"
1111#include "stringlib/count.h"
1112#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001113#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001114#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001115#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001116#include "stringlib/ctype.h"
1117#include "stringlib/transmogrify.h"
1118
1119
1120/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1121were copied from the old char* style string object. */
1122
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001123/* helper macro to fixup start/end slice values */
1124#define ADJUST_INDICES(start, end, len) \
1125 if (end > len) \
1126 end = len; \
1127 else if (end < 0) { \
1128 end += len; \
1129 if (end < 0) \
1130 end = 0; \
1131 } \
1132 if (start < 0) { \
1133 start += len; \
1134 if (start < 0) \
1135 start = 0; \
1136 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001137
1138Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001139bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001140{
1141 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001142 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001143 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001144 const char *sub;
1145 Py_ssize_t sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001146 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1147 Py_ssize_t res;
1148
Antoine Pitrouac65d962011-10-20 23:54:17 +02001149 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1150 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001151 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001152
1153 if (subobj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001154 if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001155 return -2;
1156
1157 sub = subbuf.buf;
1158 sub_len = subbuf.len;
1159 }
1160 else {
1161 sub = &byte;
1162 sub_len = 1;
1163 }
1164
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001165 if (dir > 0)
1166 res = stringlib_find_slice(
1167 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001168 sub, sub_len, start, end);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001169 else
1170 res = stringlib_rfind_slice(
1171 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001172 sub, sub_len, start, end);
1173
1174 if (subobj)
1175 PyBuffer_Release(&subbuf);
1176
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001177 return res;
1178}
1179
1180PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001181"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001182\n\
1183Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001184such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001185arguments start and end are interpreted as in slice notation.\n\
1186\n\
1187Return -1 on failure.");
1188
1189static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001190bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001191{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001192 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001193 if (result == -2)
1194 return NULL;
1195 return PyLong_FromSsize_t(result);
1196}
1197
1198PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001199"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001200\n\
1201Return the number of non-overlapping occurrences of subsection sub in\n\
1202bytes B[start:end]. Optional arguments start and end are interpreted\n\
1203as in slice notation.");
1204
1205static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001206bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001207{
1208 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001209 const char *str = PyByteArray_AS_STRING(self), *sub;
1210 Py_ssize_t sub_len;
1211 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001212 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001213
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001214 Py_buffer vsub;
1215 PyObject *count_obj;
1216
Antoine Pitrouac65d962011-10-20 23:54:17 +02001217 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1218 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001219 return NULL;
1220
Antoine Pitrouac65d962011-10-20 23:54:17 +02001221 if (sub_obj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001222 if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001223 return NULL;
1224
1225 sub = vsub.buf;
1226 sub_len = vsub.len;
1227 }
1228 else {
1229 sub = &byte;
1230 sub_len = 1;
1231 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001232
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001233 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001234
1235 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001236 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001237 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001238
1239 if (sub_obj)
1240 PyBuffer_Release(&vsub);
1241
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001242 return count_obj;
1243}
1244
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001245/*[clinic input]
1246bytearray.clear
1247
1248 self: self(type="PyByteArrayObject *")
1249
1250Remove all items from the bytearray.
1251[clinic start generated code]*/
1252
1253PyDoc_STRVAR(bytearray_clear__doc__,
1254"clear($self, /)\n"
1255"--\n"
1256"\n"
1257"Remove all items from the bytearray.");
1258
1259#define BYTEARRAY_CLEAR_METHODDEF \
1260 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, bytearray_clear__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00001261
Victor Stinner6430fd52011-09-29 04:02:13 +02001262static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001263bytearray_clear_impl(PyByteArrayObject *self);
1264
1265static PyObject *
1266bytearray_clear(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
1267{
1268 return bytearray_clear_impl(self);
1269}
1270
1271static PyObject *
1272bytearray_clear_impl(PyByteArrayObject *self)
1273/*[clinic end generated code: output=5344093031e2f36c input=e524fd330abcdc18]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001274{
1275 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1276 return NULL;
1277 Py_RETURN_NONE;
1278}
1279
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001280/*[clinic input]
1281bytearray.copy
1282
1283 self: self(type="PyByteArrayObject *")
1284
1285Return a copy of B.
1286[clinic start generated code]*/
1287
1288PyDoc_STRVAR(bytearray_copy__doc__,
1289"copy($self, /)\n"
1290"--\n"
1291"\n"
1292"Return a copy of B.");
1293
1294#define BYTEARRAY_COPY_METHODDEF \
1295 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, bytearray_copy__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00001296
1297static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001298bytearray_copy_impl(PyByteArrayObject *self);
1299
1300static PyObject *
1301bytearray_copy(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
1302{
1303 return bytearray_copy_impl(self);
1304}
1305
1306static PyObject *
1307bytearray_copy_impl(PyByteArrayObject *self)
1308/*[clinic end generated code: output=8788ed299f7f2214 input=6d5d2975aa0f33f3]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001309{
1310 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1311 PyByteArray_GET_SIZE(self));
1312}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001313
1314PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001315"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001316\n\
1317Like B.find() but raise ValueError when the subsection is not found.");
1318
1319static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001320bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001321{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001322 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001323 if (result == -2)
1324 return NULL;
1325 if (result == -1) {
1326 PyErr_SetString(PyExc_ValueError,
1327 "subsection not found");
1328 return NULL;
1329 }
1330 return PyLong_FromSsize_t(result);
1331}
1332
1333
1334PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001335"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001336\n\
1337Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001338such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001339arguments start and end are interpreted as in slice notation.\n\
1340\n\
1341Return -1 on failure.");
1342
1343static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001344bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001345{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001346 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001347 if (result == -2)
1348 return NULL;
1349 return PyLong_FromSsize_t(result);
1350}
1351
1352
1353PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001354"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001355\n\
1356Like B.rfind() but raise ValueError when the subsection is not found.");
1357
1358static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001359bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001360{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001361 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001362 if (result == -2)
1363 return NULL;
1364 if (result == -1) {
1365 PyErr_SetString(PyExc_ValueError,
1366 "subsection not found");
1367 return NULL;
1368 }
1369 return PyLong_FromSsize_t(result);
1370}
1371
1372
1373static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001374bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001375{
1376 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1377 if (ival == -1 && PyErr_Occurred()) {
1378 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001379 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001380 PyErr_Clear();
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001381 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001382 return -1;
1383 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1384 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001385 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001386 return pos >= 0;
1387 }
1388 if (ival < 0 || ival >= 256) {
1389 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1390 return -1;
1391 }
1392
Antoine Pitrou0010d372010-08-15 17:12:55 +00001393 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001394}
1395
1396
1397/* Matches the end (direction >= 0) or start (direction < 0) of self
1398 * against substr, using the start and end arguments. Returns
1399 * -1 on error, 0 if not found and 1 if found.
1400 */
1401Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001402_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001403 Py_ssize_t end, int direction)
1404{
1405 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1406 const char* str;
1407 Py_buffer vsubstr;
1408 int rv = 0;
1409
1410 str = PyByteArray_AS_STRING(self);
1411
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001412 if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001413 return -1;
1414
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001415 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001416
1417 if (direction < 0) {
1418 /* startswith */
1419 if (start+vsubstr.len > len) {
1420 goto done;
1421 }
1422 } else {
1423 /* endswith */
1424 if (end-start < vsubstr.len || start > len) {
1425 goto done;
1426 }
1427
1428 if (end-vsubstr.len > start)
1429 start = end - vsubstr.len;
1430 }
1431 if (end-start >= vsubstr.len)
1432 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1433
1434done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001435 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001436 return rv;
1437}
1438
1439
1440PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001441"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001442\n\
1443Return True if B starts with the specified prefix, False otherwise.\n\
1444With optional start, test B beginning at that position.\n\
1445With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001446prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001447
1448static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001449bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001450{
1451 Py_ssize_t start = 0;
1452 Py_ssize_t end = PY_SSIZE_T_MAX;
1453 PyObject *subobj;
1454 int result;
1455
Jesus Ceaac451502011-04-20 17:09:23 +02001456 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001457 return NULL;
1458 if (PyTuple_Check(subobj)) {
1459 Py_ssize_t i;
1460 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001461 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001462 PyTuple_GET_ITEM(subobj, i),
1463 start, end, -1);
1464 if (result == -1)
1465 return NULL;
1466 else if (result) {
1467 Py_RETURN_TRUE;
1468 }
1469 }
1470 Py_RETURN_FALSE;
1471 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001472 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001473 if (result == -1) {
1474 if (PyErr_ExceptionMatches(PyExc_TypeError))
1475 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1476 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001477 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001478 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001479 else
1480 return PyBool_FromLong(result);
1481}
1482
1483PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001484"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001485\n\
1486Return True if B ends with the specified suffix, False otherwise.\n\
1487With optional start, test B beginning at that position.\n\
1488With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001489suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001490
1491static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001492bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001493{
1494 Py_ssize_t start = 0;
1495 Py_ssize_t end = PY_SSIZE_T_MAX;
1496 PyObject *subobj;
1497 int result;
1498
Jesus Ceaac451502011-04-20 17:09:23 +02001499 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001500 return NULL;
1501 if (PyTuple_Check(subobj)) {
1502 Py_ssize_t i;
1503 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001504 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001505 PyTuple_GET_ITEM(subobj, i),
1506 start, end, +1);
1507 if (result == -1)
1508 return NULL;
1509 else if (result) {
1510 Py_RETURN_TRUE;
1511 }
1512 }
1513 Py_RETURN_FALSE;
1514 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001515 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001516 if (result == -1) {
1517 if (PyErr_ExceptionMatches(PyExc_TypeError))
1518 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1519 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001520 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001521 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001522 else
1523 return PyBool_FromLong(result);
1524}
1525
1526
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001527/*[clinic input]
1528bytearray.translate
1529
1530 self: self(type="PyByteArrayObject *")
1531 table: object
1532 Translation table, which must be a bytes object of length 256.
1533 [
1534 deletechars: object
1535 ]
1536 /
1537
1538Return a copy with each character mapped by the given translation table.
1539
1540All characters occurring in the optional argument deletechars are removed.
1541The remaining characters are mapped through the given translation table.
1542[clinic start generated code]*/
1543
1544PyDoc_STRVAR(bytearray_translate__doc__,
1545"translate(table, [deletechars])\n"
1546"Return a copy with each character mapped by the given translation table.\n"
1547"\n"
1548" table\n"
1549" Translation table, which must be a bytes object of length 256.\n"
1550"\n"
1551"All characters occurring in the optional argument deletechars are removed.\n"
1552"The remaining characters are mapped through the given translation table.");
1553
1554#define BYTEARRAY_TRANSLATE_METHODDEF \
1555 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, bytearray_translate__doc__},
1556
1557static PyObject *
1558bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_right_1, PyObject *deletechars);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001559
1560static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001561bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001562{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001563 PyObject *return_value = NULL;
1564 PyObject *table;
1565 int group_right_1 = 0;
1566 PyObject *deletechars = NULL;
1567
1568 switch (PyTuple_GET_SIZE(args)) {
1569 case 1:
1570 if (!PyArg_ParseTuple(args, "O:translate", &table))
1571 goto exit;
1572 break;
1573 case 2:
1574 if (!PyArg_ParseTuple(args, "OO:translate", &table, &deletechars))
1575 goto exit;
1576 group_right_1 = 1;
1577 break;
1578 default:
1579 PyErr_SetString(PyExc_TypeError, "bytearray.translate requires 1 to 2 arguments");
1580 goto exit;
1581 }
1582 return_value = bytearray_translate_impl(self, table, group_right_1, deletechars);
1583
1584exit:
1585 return return_value;
1586}
1587
1588static PyObject *
1589bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_right_1, PyObject *deletechars)
1590/*[clinic end generated code: output=a709df81d41db4b7 input=b749ad85f4860824]*/
1591{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001592 char *input, *output;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001593 const char *table_chars;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001594 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001595 PyObject *input_obj = (PyObject*)self;
1596 const char *output_start;
1597 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001598 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001599 int trans_table[256];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001600 Py_buffer vtable, vdel;
1601
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001602 if (table == Py_None) {
1603 table_chars = NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001604 table = NULL;
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001605 } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001606 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001607 } else {
1608 if (vtable.len != 256) {
1609 PyErr_SetString(PyExc_ValueError,
1610 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001611 PyBuffer_Release(&vtable);
1612 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001613 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001614 table_chars = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001615 }
1616
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001617 if (deletechars != NULL) {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001618 if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001619 if (table != NULL)
Georg Brandl953152f2009-07-22 12:03:59 +00001620 PyBuffer_Release(&vtable);
1621 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001622 }
1623 }
1624 else {
1625 vdel.buf = NULL;
1626 vdel.len = 0;
1627 }
1628
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001629 inlen = PyByteArray_GET_SIZE(input_obj);
1630 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1631 if (result == NULL)
1632 goto done;
1633 output_start = output = PyByteArray_AsString(result);
1634 input = PyByteArray_AS_STRING(input_obj);
1635
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001636 if (vdel.len == 0 && table_chars != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001637 /* If no deletions are required, use faster code */
1638 for (i = inlen; --i >= 0; ) {
1639 c = Py_CHARMASK(*input++);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001640 *output++ = table_chars[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001641 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001642 goto done;
1643 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001644
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001645 if (table_chars == NULL) {
Georg Brandlccc47b62008-12-28 11:44:14 +00001646 for (i = 0; i < 256; i++)
1647 trans_table[i] = Py_CHARMASK(i);
1648 } else {
1649 for (i = 0; i < 256; i++)
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001650 trans_table[i] = Py_CHARMASK(table_chars[i]);
Georg Brandlccc47b62008-12-28 11:44:14 +00001651 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001652
1653 for (i = 0; i < vdel.len; i++)
1654 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1655
1656 for (i = inlen; --i >= 0; ) {
1657 c = Py_CHARMASK(*input++);
1658 if (trans_table[c] != -1)
1659 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1660 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001661 }
1662 /* Fix the size of the resulting string */
1663 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001664 if (PyByteArray_Resize(result, output - output_start) < 0) {
1665 Py_CLEAR(result);
1666 goto done;
1667 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001668
1669done:
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001670 if (table != NULL)
Georg Brandlccc47b62008-12-28 11:44:14 +00001671 PyBuffer_Release(&vtable);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001672 if (deletechars != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001673 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001674 return result;
1675}
1676
1677
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001678/*[clinic input]
1679
1680@staticmethod
1681bytearray.maketrans
1682
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001683 frm: Py_buffer
1684 to: Py_buffer
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001685 /
1686
1687Return a translation table useable for the bytes or bytearray translate method.
1688
1689The returned table will be one where each byte in frm is mapped to the byte at
1690the same position in to.
1691
1692The bytes objects frm and to must be of the same length.
1693[clinic start generated code]*/
1694
1695PyDoc_STRVAR(bytearray_maketrans__doc__,
1696"maketrans(frm, to, /)\n"
1697"--\n"
1698"\n"
1699"Return a translation table useable for the bytes or bytearray translate method.\n"
1700"\n"
1701"The returned table will be one where each byte in frm is mapped to the byte at\n"
1702"the same position in to.\n"
1703"\n"
1704"The bytes objects frm and to must be of the same length.");
1705
1706#define BYTEARRAY_MAKETRANS_METHODDEF \
1707 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC, bytearray_maketrans__doc__},
1708
Georg Brandlabc38772009-04-12 15:51:51 +00001709static PyObject *
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001710bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001711
1712static PyObject *
1713bytearray_maketrans(void *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001714{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001715 PyObject *return_value = NULL;
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001716 Py_buffer frm = {NULL, NULL};
1717 Py_buffer to = {NULL, NULL};
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001718
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001719 if (!PyArg_ParseTuple(args,
1720 "y*y*:maketrans",
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001721 &frm, &to))
1722 goto exit;
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001723 return_value = bytearray_maketrans_impl(&frm, &to);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001724
1725exit:
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001726 /* Cleanup for frm */
1727 if (frm.obj)
1728 PyBuffer_Release(&frm);
1729 /* Cleanup for to */
1730 if (to.obj)
1731 PyBuffer_Release(&to);
1732
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001733 return return_value;
1734}
1735
1736static PyObject *
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001737bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
1738/*[clinic end generated code: output=d332622814c26f4b input=5925a81d2fbbf151]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001739{
1740 return _Py_bytes_maketrans(frm, to);
Georg Brandlabc38772009-04-12 15:51:51 +00001741}
1742
1743
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001744/* find and count characters and substrings */
1745
1746#define findchar(target, target_len, c) \
1747 ((char *)memchr((const void *)(target), c, target_len))
1748
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001749
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001750/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001751Py_LOCAL(PyByteArrayObject *)
1752return_self(PyByteArrayObject *self)
1753{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001754 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001755 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1756 PyByteArray_AS_STRING(self),
1757 PyByteArray_GET_SIZE(self));
1758}
1759
1760Py_LOCAL_INLINE(Py_ssize_t)
1761countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1762{
1763 Py_ssize_t count=0;
1764 const char *start=target;
1765 const char *end=target+target_len;
1766
1767 while ( (start=findchar(start, end-start, c)) != NULL ) {
1768 count++;
1769 if (count >= maxcount)
1770 break;
1771 start += 1;
1772 }
1773 return count;
1774}
1775
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001776
1777/* Algorithms for different cases of string replacement */
1778
1779/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1780Py_LOCAL(PyByteArrayObject *)
1781replace_interleave(PyByteArrayObject *self,
1782 const char *to_s, Py_ssize_t to_len,
1783 Py_ssize_t maxcount)
1784{
1785 char *self_s, *result_s;
1786 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001787 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001788 PyByteArrayObject *result;
1789
1790 self_len = PyByteArray_GET_SIZE(self);
1791
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001792 /* 1 at the end plus 1 after every character;
1793 count = min(maxcount, self_len + 1) */
1794 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001795 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001796 else
1797 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1798 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001799
1800 /* Check for overflow */
1801 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001802 assert(count > 0);
1803 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001804 PyErr_SetString(PyExc_OverflowError,
1805 "replace string is too long");
1806 return NULL;
1807 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001808 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001809
1810 if (! (result = (PyByteArrayObject *)
1811 PyByteArray_FromStringAndSize(NULL, result_len)) )
1812 return NULL;
1813
1814 self_s = PyByteArray_AS_STRING(self);
1815 result_s = PyByteArray_AS_STRING(result);
1816
1817 /* TODO: special case single character, which doesn't need memcpy */
1818
1819 /* Lay the first one down (guaranteed this will occur) */
1820 Py_MEMCPY(result_s, to_s, to_len);
1821 result_s += to_len;
1822 count -= 1;
1823
1824 for (i=0; i<count; i++) {
1825 *result_s++ = *self_s++;
1826 Py_MEMCPY(result_s, to_s, to_len);
1827 result_s += to_len;
1828 }
1829
1830 /* Copy the rest of the original string */
1831 Py_MEMCPY(result_s, self_s, self_len-i);
1832
1833 return result;
1834}
1835
1836/* Special case for deleting a single character */
1837/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1838Py_LOCAL(PyByteArrayObject *)
1839replace_delete_single_character(PyByteArrayObject *self,
1840 char from_c, Py_ssize_t maxcount)
1841{
1842 char *self_s, *result_s;
1843 char *start, *next, *end;
1844 Py_ssize_t self_len, result_len;
1845 Py_ssize_t count;
1846 PyByteArrayObject *result;
1847
1848 self_len = PyByteArray_GET_SIZE(self);
1849 self_s = PyByteArray_AS_STRING(self);
1850
1851 count = countchar(self_s, self_len, from_c, maxcount);
1852 if (count == 0) {
1853 return return_self(self);
1854 }
1855
1856 result_len = self_len - count; /* from_len == 1 */
1857 assert(result_len>=0);
1858
1859 if ( (result = (PyByteArrayObject *)
1860 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1861 return NULL;
1862 result_s = PyByteArray_AS_STRING(result);
1863
1864 start = self_s;
1865 end = self_s + self_len;
1866 while (count-- > 0) {
1867 next = findchar(start, end-start, from_c);
1868 if (next == NULL)
1869 break;
1870 Py_MEMCPY(result_s, start, next-start);
1871 result_s += (next-start);
1872 start = next+1;
1873 }
1874 Py_MEMCPY(result_s, start, end-start);
1875
1876 return result;
1877}
1878
1879/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1880
1881Py_LOCAL(PyByteArrayObject *)
1882replace_delete_substring(PyByteArrayObject *self,
1883 const char *from_s, Py_ssize_t from_len,
1884 Py_ssize_t maxcount)
1885{
1886 char *self_s, *result_s;
1887 char *start, *next, *end;
1888 Py_ssize_t self_len, result_len;
1889 Py_ssize_t count, offset;
1890 PyByteArrayObject *result;
1891
1892 self_len = PyByteArray_GET_SIZE(self);
1893 self_s = PyByteArray_AS_STRING(self);
1894
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001895 count = stringlib_count(self_s, self_len,
1896 from_s, from_len,
1897 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001898
1899 if (count == 0) {
1900 /* no matches */
1901 return return_self(self);
1902 }
1903
1904 result_len = self_len - (count * from_len);
1905 assert (result_len>=0);
1906
1907 if ( (result = (PyByteArrayObject *)
1908 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1909 return NULL;
1910
1911 result_s = PyByteArray_AS_STRING(result);
1912
1913 start = self_s;
1914 end = self_s + self_len;
1915 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001916 offset = stringlib_find(start, end-start,
1917 from_s, from_len,
1918 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001919 if (offset == -1)
1920 break;
1921 next = start + offset;
1922
1923 Py_MEMCPY(result_s, start, next-start);
1924
1925 result_s += (next-start);
1926 start = next+from_len;
1927 }
1928 Py_MEMCPY(result_s, start, end-start);
1929 return result;
1930}
1931
1932/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1933Py_LOCAL(PyByteArrayObject *)
1934replace_single_character_in_place(PyByteArrayObject *self,
1935 char from_c, char to_c,
1936 Py_ssize_t maxcount)
1937{
Antoine Pitroud1188562010-06-09 16:38:55 +00001938 char *self_s, *result_s, *start, *end, *next;
1939 Py_ssize_t self_len;
1940 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001941
Antoine Pitroud1188562010-06-09 16:38:55 +00001942 /* The result string will be the same size */
1943 self_s = PyByteArray_AS_STRING(self);
1944 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001945
Antoine Pitroud1188562010-06-09 16:38:55 +00001946 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001947
Antoine Pitroud1188562010-06-09 16:38:55 +00001948 if (next == NULL) {
1949 /* No matches; return the original bytes */
1950 return return_self(self);
1951 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001952
Antoine Pitroud1188562010-06-09 16:38:55 +00001953 /* Need to make a new bytes */
1954 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1955 if (result == NULL)
1956 return NULL;
1957 result_s = PyByteArray_AS_STRING(result);
1958 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001959
Antoine Pitroud1188562010-06-09 16:38:55 +00001960 /* change everything in-place, starting with this one */
1961 start = result_s + (next-self_s);
1962 *start = to_c;
1963 start++;
1964 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001965
Antoine Pitroud1188562010-06-09 16:38:55 +00001966 while (--maxcount > 0) {
1967 next = findchar(start, end-start, from_c);
1968 if (next == NULL)
1969 break;
1970 *next = to_c;
1971 start = next+1;
1972 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001973
Antoine Pitroud1188562010-06-09 16:38:55 +00001974 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001975}
1976
1977/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1978Py_LOCAL(PyByteArrayObject *)
1979replace_substring_in_place(PyByteArrayObject *self,
1980 const char *from_s, Py_ssize_t from_len,
1981 const char *to_s, Py_ssize_t to_len,
1982 Py_ssize_t maxcount)
1983{
1984 char *result_s, *start, *end;
1985 char *self_s;
1986 Py_ssize_t self_len, offset;
1987 PyByteArrayObject *result;
1988
1989 /* The result bytes will be the same size */
1990
1991 self_s = PyByteArray_AS_STRING(self);
1992 self_len = PyByteArray_GET_SIZE(self);
1993
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001994 offset = stringlib_find(self_s, self_len,
1995 from_s, from_len,
1996 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001997 if (offset == -1) {
1998 /* No matches; return the original bytes */
1999 return return_self(self);
2000 }
2001
2002 /* Need to make a new bytes */
2003 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
2004 if (result == NULL)
2005 return NULL;
2006 result_s = PyByteArray_AS_STRING(result);
2007 Py_MEMCPY(result_s, self_s, self_len);
2008
2009 /* change everything in-place, starting with this one */
2010 start = result_s + offset;
2011 Py_MEMCPY(start, to_s, from_len);
2012 start += from_len;
2013 end = result_s + self_len;
2014
2015 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002016 offset = stringlib_find(start, end-start,
2017 from_s, from_len,
2018 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002019 if (offset==-1)
2020 break;
2021 Py_MEMCPY(start+offset, to_s, from_len);
2022 start += offset+from_len;
2023 }
2024
2025 return result;
2026}
2027
2028/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
2029Py_LOCAL(PyByteArrayObject *)
2030replace_single_character(PyByteArrayObject *self,
2031 char from_c,
2032 const char *to_s, Py_ssize_t to_len,
2033 Py_ssize_t maxcount)
2034{
2035 char *self_s, *result_s;
2036 char *start, *next, *end;
2037 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002038 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002039 PyByteArrayObject *result;
2040
2041 self_s = PyByteArray_AS_STRING(self);
2042 self_len = PyByteArray_GET_SIZE(self);
2043
2044 count = countchar(self_s, self_len, from_c, maxcount);
2045 if (count == 0) {
2046 /* no matches, return unchanged */
2047 return return_self(self);
2048 }
2049
2050 /* use the difference between current and new, hence the "-1" */
2051 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002052 assert(count > 0);
2053 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002054 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
2055 return NULL;
2056 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002057 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002058
2059 if ( (result = (PyByteArrayObject *)
2060 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
2061 return NULL;
2062 result_s = PyByteArray_AS_STRING(result);
2063
2064 start = self_s;
2065 end = self_s + self_len;
2066 while (count-- > 0) {
2067 next = findchar(start, end-start, from_c);
2068 if (next == NULL)
2069 break;
2070
2071 if (next == start) {
2072 /* replace with the 'to' */
2073 Py_MEMCPY(result_s, to_s, to_len);
2074 result_s += to_len;
2075 start += 1;
2076 } else {
2077 /* copy the unchanged old then the 'to' */
2078 Py_MEMCPY(result_s, start, next-start);
2079 result_s += (next-start);
2080 Py_MEMCPY(result_s, to_s, to_len);
2081 result_s += to_len;
2082 start = next+1;
2083 }
2084 }
2085 /* Copy the remainder of the remaining bytes */
2086 Py_MEMCPY(result_s, start, end-start);
2087
2088 return result;
2089}
2090
2091/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
2092Py_LOCAL(PyByteArrayObject *)
2093replace_substring(PyByteArrayObject *self,
2094 const char *from_s, Py_ssize_t from_len,
2095 const char *to_s, Py_ssize_t to_len,
2096 Py_ssize_t maxcount)
2097{
2098 char *self_s, *result_s;
2099 char *start, *next, *end;
2100 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002101 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002102 PyByteArrayObject *result;
2103
2104 self_s = PyByteArray_AS_STRING(self);
2105 self_len = PyByteArray_GET_SIZE(self);
2106
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002107 count = stringlib_count(self_s, self_len,
2108 from_s, from_len,
2109 maxcount);
2110
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002111 if (count == 0) {
2112 /* no matches, return unchanged */
2113 return return_self(self);
2114 }
2115
2116 /* Check for overflow */
2117 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002118 assert(count > 0);
2119 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002120 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
2121 return NULL;
2122 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002123 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002124
2125 if ( (result = (PyByteArrayObject *)
2126 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
2127 return NULL;
2128 result_s = PyByteArray_AS_STRING(result);
2129
2130 start = self_s;
2131 end = self_s + self_len;
2132 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002133 offset = stringlib_find(start, end-start,
2134 from_s, from_len,
2135 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002136 if (offset == -1)
2137 break;
2138 next = start+offset;
2139 if (next == start) {
2140 /* replace with the 'to' */
2141 Py_MEMCPY(result_s, to_s, to_len);
2142 result_s += to_len;
2143 start += from_len;
2144 } else {
2145 /* copy the unchanged old then the 'to' */
2146 Py_MEMCPY(result_s, start, next-start);
2147 result_s += (next-start);
2148 Py_MEMCPY(result_s, to_s, to_len);
2149 result_s += to_len;
2150 start = next+from_len;
2151 }
2152 }
2153 /* Copy the remainder of the remaining bytes */
2154 Py_MEMCPY(result_s, start, end-start);
2155
2156 return result;
2157}
2158
2159
2160Py_LOCAL(PyByteArrayObject *)
2161replace(PyByteArrayObject *self,
2162 const char *from_s, Py_ssize_t from_len,
2163 const char *to_s, Py_ssize_t to_len,
2164 Py_ssize_t maxcount)
2165{
2166 if (maxcount < 0) {
2167 maxcount = PY_SSIZE_T_MAX;
2168 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
2169 /* nothing to do; return the original bytes */
2170 return return_self(self);
2171 }
2172
2173 if (maxcount == 0 ||
2174 (from_len == 0 && to_len == 0)) {
2175 /* nothing to do; return the original bytes */
2176 return return_self(self);
2177 }
2178
2179 /* Handle zero-length special cases */
2180
2181 if (from_len == 0) {
2182 /* insert the 'to' bytes everywhere. */
2183 /* >>> "Python".replace("", ".") */
2184 /* '.P.y.t.h.o.n.' */
2185 return replace_interleave(self, to_s, to_len, maxcount);
2186 }
2187
2188 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2189 /* point for an empty self bytes to generate a non-empty bytes */
2190 /* Special case so the remaining code always gets a non-empty bytes */
2191 if (PyByteArray_GET_SIZE(self) == 0) {
2192 return return_self(self);
2193 }
2194
2195 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002196 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002197 if (from_len == 1) {
2198 return replace_delete_single_character(
2199 self, from_s[0], maxcount);
2200 } else {
2201 return replace_delete_substring(self, from_s, from_len, maxcount);
2202 }
2203 }
2204
2205 /* Handle special case where both bytes have the same length */
2206
2207 if (from_len == to_len) {
2208 if (from_len == 1) {
2209 return replace_single_character_in_place(
2210 self,
2211 from_s[0],
2212 to_s[0],
2213 maxcount);
2214 } else {
2215 return replace_substring_in_place(
2216 self, from_s, from_len, to_s, to_len, maxcount);
2217 }
2218 }
2219
2220 /* Otherwise use the more generic algorithms */
2221 if (from_len == 1) {
2222 return replace_single_character(self, from_s[0],
2223 to_s, to_len, maxcount);
2224 } else {
2225 /* len('from')>=2, len('to')>=1 */
2226 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2227 }
2228}
2229
2230
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002231/*[clinic input]
2232bytearray.replace
2233
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002234 old: Py_buffer
2235 new: Py_buffer
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002236 count: Py_ssize_t = -1
2237 Maximum number of occurrences to replace.
2238 -1 (the default value) means replace all occurrences.
2239 /
2240
2241Return a copy with all occurrences of substring old replaced by new.
2242
2243If the optional argument count is given, only the first count occurrences are
2244replaced.
2245[clinic start generated code]*/
2246
2247PyDoc_STRVAR(bytearray_replace__doc__,
2248"replace($self, old, new, count=-1, /)\n"
2249"--\n"
2250"\n"
2251"Return a copy with all occurrences of substring old replaced by new.\n"
2252"\n"
2253" count\n"
2254" Maximum number of occurrences to replace.\n"
2255" -1 (the default value) means replace all occurrences.\n"
2256"\n"
2257"If the optional argument count is given, only the first count occurrences are\n"
2258"replaced.");
2259
2260#define BYTEARRAY_REPLACE_METHODDEF \
2261 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, bytearray_replace__doc__},
2262
2263static PyObject *
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002264bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old, Py_buffer *new, Py_ssize_t count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002265
2266static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002267bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002268{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002269 PyObject *return_value = NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002270 Py_buffer old = {NULL, NULL};
2271 Py_buffer new = {NULL, NULL};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002272 Py_ssize_t count = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002273
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002274 if (!PyArg_ParseTuple(args,
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002275 "y*y*|n:replace",
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002276 &old, &new, &count))
2277 goto exit;
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002278 return_value = bytearray_replace_impl(self, &old, &new, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002279
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002280exit:
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002281 /* Cleanup for old */
2282 if (old.obj)
2283 PyBuffer_Release(&old);
2284 /* Cleanup for new */
2285 if (new.obj)
2286 PyBuffer_Release(&new);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002287
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002288 return return_value;
2289}
2290
2291static PyObject *
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002292bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old, Py_buffer *new, Py_ssize_t count)
2293/*[clinic end generated code: output=9997fbbd5bac4883 input=aa379d988637c7fb]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002294{
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002295 return (PyObject *)replace((PyByteArrayObject *) self,
2296 old->buf, old->len,
2297 new->buf, new->len, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002298}
2299
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002300/*[clinic input]
2301bytearray.split
2302
2303 sep: object = None
2304 The delimiter according which to split the bytearray.
2305 None (the default value) means split on ASCII whitespace characters
2306 (space, tab, return, newline, formfeed, vertical tab).
2307 maxsplit: Py_ssize_t = -1
2308 Maximum number of splits to do.
2309 -1 (the default value) means no limit.
2310
2311Return a list of the sections in the bytearray, using sep as the delimiter.
2312[clinic start generated code]*/
2313
2314PyDoc_STRVAR(bytearray_split__doc__,
2315"split($self, /, sep=None, maxsplit=-1)\n"
2316"--\n"
2317"\n"
2318"Return a list of the sections in the bytearray, using sep as the delimiter.\n"
2319"\n"
2320" sep\n"
2321" The delimiter according which to split the bytearray.\n"
2322" None (the default value) means split on ASCII whitespace characters\n"
2323" (space, tab, return, newline, formfeed, vertical tab).\n"
2324" maxsplit\n"
2325" Maximum number of splits to do.\n"
2326" -1 (the default value) means no limit.");
2327
2328#define BYTEARRAY_SPLIT_METHODDEF \
2329 {"split", (PyCFunction)bytearray_split, METH_VARARGS|METH_KEYWORDS, bytearray_split__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002330
2331static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002332bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit);
2333
2334static PyObject *
2335bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002336{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002337 PyObject *return_value = NULL;
2338 static char *_keywords[] = {"sep", "maxsplit", NULL};
2339 PyObject *sep = Py_None;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002340 Py_ssize_t maxsplit = -1;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002341
2342 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2343 "|On:split", _keywords,
2344 &sep, &maxsplit))
2345 goto exit;
2346 return_value = bytearray_split_impl(self, sep, maxsplit);
2347
2348exit:
2349 return return_value;
2350}
2351
2352static PyObject *
2353bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit)
2354/*[clinic end generated code: output=062a3d87d6f918fa input=24f82669f41bf523]*/
2355{
2356 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002357 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002358 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002359 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002360
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002361 if (maxsplit < 0)
2362 maxsplit = PY_SSIZE_T_MAX;
2363
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002364 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002365 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002366
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002367 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002368 return NULL;
2369 sub = vsub.buf;
2370 n = vsub.len;
2371
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002372 list = stringlib_split(
2373 (PyObject*) self, s, len, sub, n, maxsplit
2374 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002375 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002376 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002377}
2378
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002379/*[clinic input]
2380bytearray.partition
2381
2382 self: self(type="PyByteArrayObject *")
2383 sep: object
2384 /
2385
2386Partition the bytearray into three parts using the given separator.
2387
2388This will search for the separator sep in the bytearray. If the separator is
2389found, returns a 3-tuple containing the part before the separator, the
2390separator itself, and the part after it.
2391
2392If the separator is not found, returns a 3-tuple containing the original
2393bytearray object and two empty bytearray objects.
2394[clinic start generated code]*/
2395
2396PyDoc_STRVAR(bytearray_partition__doc__,
2397"partition($self, sep, /)\n"
2398"--\n"
2399"\n"
2400"Partition the bytearray into three parts using the given separator.\n"
2401"\n"
2402"This will search for the separator sep in the bytearray. If the separator is\n"
2403"found, returns a 3-tuple containing the part before the separator, the\n"
2404"separator itself, and the part after it.\n"
2405"\n"
2406"If the separator is not found, returns a 3-tuple containing the original\n"
2407"bytearray object and two empty bytearray objects.");
2408
2409#define BYTEARRAY_PARTITION_METHODDEF \
2410 {"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002411
2412static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002413bytearray_partition(PyByteArrayObject *self, PyObject *sep)
2414/*[clinic end generated code: output=2645138221fe6f4d input=7d7fe37b1696d506]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002415{
2416 PyObject *bytesep, *result;
2417
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002418 bytesep = PyByteArray_FromObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002419 if (! bytesep)
2420 return NULL;
2421
2422 result = stringlib_partition(
2423 (PyObject*) self,
2424 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2425 bytesep,
2426 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2427 );
2428
2429 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002430 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002431}
2432
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002433/*[clinic input]
2434bytearray.rpartition
2435
2436 self: self(type="PyByteArrayObject *")
2437 sep: object
2438 /
2439
2440Partition the bytes into three parts using the given separator.
2441
2442This will search for the separator sep in the bytearray, starting and the end.
2443If the separator is found, returns a 3-tuple containing the part before the
2444separator, the separator itself, and the part after it.
2445
2446If the separator is not found, returns a 3-tuple containing two empty bytearray
2447objects and the original bytearray object.
2448[clinic start generated code]*/
2449
2450PyDoc_STRVAR(bytearray_rpartition__doc__,
2451"rpartition($self, sep, /)\n"
2452"--\n"
2453"\n"
2454"Partition the bytes into three parts using the given separator.\n"
2455"\n"
2456"This will search for the separator sep in the bytearray, starting and the end.\n"
2457"If the separator is found, returns a 3-tuple containing the part before the\n"
2458"separator, the separator itself, and the part after it.\n"
2459"\n"
2460"If the separator is not found, returns a 3-tuple containing two empty bytearray\n"
2461"objects and the original bytearray object.");
2462
2463#define BYTEARRAY_RPARTITION_METHODDEF \
2464 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002465
2466static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002467bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
2468/*[clinic end generated code: output=ed13e54605d007de input=9b8cd540c1b75853]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002469{
2470 PyObject *bytesep, *result;
2471
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002472 bytesep = PyByteArray_FromObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002473 if (! bytesep)
2474 return NULL;
2475
2476 result = stringlib_rpartition(
2477 (PyObject*) self,
2478 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2479 bytesep,
2480 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2481 );
2482
2483 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002484 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002485}
2486
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002487/*[clinic input]
2488bytearray.rsplit = bytearray.split
2489
2490Return a list of the sections in the bytearray, using sep as the delimiter.
2491
2492Splitting is done starting at the end of the bytearray and working to the front.
2493[clinic start generated code]*/
2494
2495PyDoc_STRVAR(bytearray_rsplit__doc__,
2496"rsplit($self, /, sep=None, maxsplit=-1)\n"
2497"--\n"
2498"\n"
2499"Return a list of the sections in the bytearray, using sep as the delimiter.\n"
2500"\n"
2501" sep\n"
2502" The delimiter according which to split the bytearray.\n"
2503" None (the default value) means split on ASCII whitespace characters\n"
2504" (space, tab, return, newline, formfeed, vertical tab).\n"
2505" maxsplit\n"
2506" Maximum number of splits to do.\n"
2507" -1 (the default value) means no limit.\n"
2508"\n"
2509"Splitting is done starting at the end of the bytearray and working to the front.");
2510
2511#define BYTEARRAY_RSPLIT_METHODDEF \
2512 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS|METH_KEYWORDS, bytearray_rsplit__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002513
2514static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002515bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit);
2516
2517static PyObject *
2518bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002519{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002520 PyObject *return_value = NULL;
2521 static char *_keywords[] = {"sep", "maxsplit", NULL};
2522 PyObject *sep = Py_None;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002523 Py_ssize_t maxsplit = -1;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002524
2525 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2526 "|On:rsplit", _keywords,
2527 &sep, &maxsplit))
2528 goto exit;
2529 return_value = bytearray_rsplit_impl(self, sep, maxsplit);
2530
2531exit:
2532 return return_value;
2533}
2534
2535static PyObject *
2536bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit)
2537/*[clinic end generated code: output=affaf9fc2aae8d41 input=a68286e4dd692ffe]*/
2538{
2539 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002540 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002541 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002542 Py_buffer vsub;
2543
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002544 if (maxsplit < 0)
2545 maxsplit = PY_SSIZE_T_MAX;
2546
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002547 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002548 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002549
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002550 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002551 return NULL;
2552 sub = vsub.buf;
2553 n = vsub.len;
2554
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002555 list = stringlib_rsplit(
2556 (PyObject*) self, s, len, sub, n, maxsplit
2557 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002558 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002559 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002560}
2561
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002562/*[clinic input]
2563bytearray.reverse
2564
2565 self: self(type="PyByteArrayObject *")
2566
2567Reverse the order of the values in B in place.
2568[clinic start generated code]*/
2569
2570PyDoc_STRVAR(bytearray_reverse__doc__,
2571"reverse($self, /)\n"
2572"--\n"
2573"\n"
2574"Reverse the order of the values in B in place.");
2575
2576#define BYTEARRAY_REVERSE_METHODDEF \
2577 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, bytearray_reverse__doc__},
2578
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002579static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002580bytearray_reverse_impl(PyByteArrayObject *self);
2581
2582static PyObject *
2583bytearray_reverse(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
2584{
2585 return bytearray_reverse_impl(self);
2586}
2587
2588static PyObject *
2589bytearray_reverse_impl(PyByteArrayObject *self)
2590/*[clinic end generated code: output=5d5e5f0bfc67f476 input=7933a499b8597bd1]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002591{
2592 char swap, *head, *tail;
2593 Py_ssize_t i, j, n = Py_SIZE(self);
2594
2595 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002596 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002597 tail = head + n - 1;
2598 for (i = 0; i < j; i++) {
2599 swap = *head;
2600 *head++ = *tail;
2601 *tail-- = swap;
2602 }
2603
2604 Py_RETURN_NONE;
2605}
2606
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002607
2608/*[python input]
2609class bytesvalue_converter(CConverter):
2610 type = 'int'
2611 converter = '_getbytevalue'
2612[python start generated code]*/
2613/*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
2614
2615
2616/*[clinic input]
2617bytearray.insert
2618
2619 self: self(type="PyByteArrayObject *")
2620 index: Py_ssize_t
2621 The index where the value is to be inserted.
2622 item: bytesvalue
2623 The item to be inserted.
2624 /
2625
2626Insert a single item into the bytearray before the given index.
2627[clinic start generated code]*/
2628
2629PyDoc_STRVAR(bytearray_insert__doc__,
2630"insert($self, index, item, /)\n"
2631"--\n"
2632"\n"
2633"Insert a single item into the bytearray before the given index.\n"
2634"\n"
2635" index\n"
2636" The index where the value is to be inserted.\n"
2637" item\n"
2638" The item to be inserted.");
2639
2640#define BYTEARRAY_INSERT_METHODDEF \
2641 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, bytearray_insert__doc__},
2642
2643static PyObject *
2644bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item);
2645
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002646static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002647bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002648{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002649 PyObject *return_value = NULL;
2650 Py_ssize_t index;
2651 int item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002652
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002653 if (!PyArg_ParseTuple(args,
2654 "nO&:insert",
2655 &index, _getbytevalue, &item))
2656 goto exit;
2657 return_value = bytearray_insert_impl(self, index, item);
2658
2659exit:
2660 return return_value;
2661}
2662
2663static PyObject *
2664bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
2665/*[clinic end generated code: output=5ec9340d4ad19080 input=833766836ba30e1e]*/
2666{
2667 Py_ssize_t n = Py_SIZE(self);
2668 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002669
2670 if (n == PY_SSIZE_T_MAX) {
2671 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002672 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002673 return NULL;
2674 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002675 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2676 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002677 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002678
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002679 if (index < 0) {
2680 index += n;
2681 if (index < 0)
2682 index = 0;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002683 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002684 if (index > n)
2685 index = n;
2686 memmove(buf + index + 1, buf + index, n - index);
2687 buf[index] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002688
2689 Py_RETURN_NONE;
2690}
2691
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002692/*[clinic input]
2693bytearray.append
2694
2695 self: self(type="PyByteArrayObject *")
2696 item: bytesvalue
2697 The item to be appended.
2698 /
2699
2700Append a single item to the end of the bytearray.
2701[clinic start generated code]*/
2702
2703PyDoc_STRVAR(bytearray_append__doc__,
2704"append($self, item, /)\n"
2705"--\n"
2706"\n"
2707"Append a single item to the end of the bytearray.\n"
2708"\n"
2709" item\n"
2710" The item to be appended.");
2711
2712#define BYTEARRAY_APPEND_METHODDEF \
2713 {"append", (PyCFunction)bytearray_append, METH_VARARGS, bytearray_append__doc__},
2714
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002715static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002716bytearray_append_impl(PyByteArrayObject *self, int item);
2717
2718static PyObject *
2719bytearray_append(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002720{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002721 PyObject *return_value = NULL;
2722 int item;
2723
2724 if (!PyArg_ParseTuple(args,
2725 "O&:append",
2726 _getbytevalue, &item))
2727 goto exit;
2728 return_value = bytearray_append_impl(self, item);
2729
2730exit:
2731 return return_value;
2732}
2733
2734static PyObject *
2735bytearray_append_impl(PyByteArrayObject *self, int item)
2736/*[clinic end generated code: output=b5b3325bb3bbaf85 input=ae56ea87380407cc]*/
2737{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002738 Py_ssize_t n = Py_SIZE(self);
2739
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002740 if (n == PY_SSIZE_T_MAX) {
2741 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002742 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002743 return NULL;
2744 }
2745 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2746 return NULL;
2747
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002748 PyByteArray_AS_STRING(self)[n] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002749
2750 Py_RETURN_NONE;
2751}
2752
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002753/*[clinic input]
2754bytearray.extend
2755
2756 self: self(type="PyByteArrayObject *")
2757 iterable_of_ints: object
2758 The iterable of items to append.
2759 /
2760
2761Append all the items from the iterator or sequence to the end of the bytearray.
2762[clinic start generated code]*/
2763
2764PyDoc_STRVAR(bytearray_extend__doc__,
2765"extend($self, iterable_of_ints, /)\n"
2766"--\n"
2767"\n"
2768"Append all the items from the iterator or sequence to the end of the bytearray.\n"
2769"\n"
2770" iterable_of_ints\n"
2771" The iterable of items to append.");
2772
2773#define BYTEARRAY_EXTEND_METHODDEF \
2774 {"extend", (PyCFunction)bytearray_extend, METH_O, bytearray_extend__doc__},
2775
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002776static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002777bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
2778/*[clinic end generated code: output=13b0c13ad5110dfb input=ce83a5d75b70d850]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002779{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002780 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002781 Py_ssize_t buf_size = 0, len = 0;
2782 int value;
2783 char *buf;
2784
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002785 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002786 if (PyObject_CheckBuffer(iterable_of_ints)) {
2787 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002788 return NULL;
2789
2790 Py_RETURN_NONE;
2791 }
2792
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002793 it = PyObject_GetIter(iterable_of_ints);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002794 if (it == NULL)
2795 return NULL;
2796
Ezio Melotti42da6632011-03-15 05:18:48 +02002797 /* Try to determine the length of the argument. 32 is arbitrary. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002798 buf_size = PyObject_LengthHint(iterable_of_ints, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002799 if (buf_size == -1) {
2800 Py_DECREF(it);
2801 return NULL;
2802 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002803
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002804 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002805 if (bytearray_obj == NULL) {
2806 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002807 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002808 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002809 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002810
2811 while ((item = PyIter_Next(it)) != NULL) {
2812 if (! _getbytevalue(item, &value)) {
2813 Py_DECREF(item);
2814 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002815 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002816 return NULL;
2817 }
2818 buf[len++] = value;
2819 Py_DECREF(item);
2820
2821 if (len >= buf_size) {
2822 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002823 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002824 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002825 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002826 return NULL;
2827 }
2828 /* Recompute the `buf' pointer, since the resizing operation may
2829 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002830 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002831 }
2832 }
2833 Py_DECREF(it);
2834
2835 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002836 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2837 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002838 return NULL;
2839 }
2840
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002841 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2842 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002843 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002844 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002845 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002846
2847 Py_RETURN_NONE;
2848}
2849
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002850/*[clinic input]
2851bytearray.pop
2852
2853 self: self(type="PyByteArrayObject *")
2854 index: Py_ssize_t = -1
2855 The index from where to remove the item.
2856 -1 (the default value) means remove the last item.
2857 /
2858
2859Remove and return a single item from B.
2860
2861If no index argument is given, will pop the last item.
2862[clinic start generated code]*/
2863
2864PyDoc_STRVAR(bytearray_pop__doc__,
2865"pop($self, index=-1, /)\n"
2866"--\n"
2867"\n"
2868"Remove and return a single item from B.\n"
2869"\n"
2870" index\n"
2871" The index from where to remove the item.\n"
2872" -1 (the default value) means remove the last item.\n"
2873"\n"
2874"If no index argument is given, will pop the last item.");
2875
2876#define BYTEARRAY_POP_METHODDEF \
2877 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, bytearray_pop__doc__},
2878
2879static PyObject *
2880bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index);
2881
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002882static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002883bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002884{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002885 PyObject *return_value = NULL;
2886 Py_ssize_t index = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002887
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002888 if (!PyArg_ParseTuple(args,
2889 "|n:pop",
2890 &index))
2891 goto exit;
2892 return_value = bytearray_pop_impl(self, index);
2893
2894exit:
2895 return return_value;
2896}
2897
2898static PyObject *
2899bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
2900/*[clinic end generated code: output=3b763e548e79af96 input=0797e6c0ca9d5a85]*/
2901{
2902 int value;
2903 Py_ssize_t n = Py_SIZE(self);
2904 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002905
2906 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002907 PyErr_SetString(PyExc_IndexError,
2908 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002909 return NULL;
2910 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002911 if (index < 0)
2912 index += Py_SIZE(self);
2913 if (index < 0 || index >= Py_SIZE(self)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002914 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2915 return NULL;
2916 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002917 if (!_canresize(self))
2918 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002919
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002920 buf = PyByteArray_AS_STRING(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002921 value = buf[index];
2922 memmove(buf + index, buf + index + 1, n - index);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002923 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2924 return NULL;
2925
Mark Dickinson54a3db92009-09-06 10:19:23 +00002926 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002927}
2928
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002929/*[clinic input]
2930bytearray.remove
2931
2932 self: self(type="PyByteArrayObject *")
2933 value: bytesvalue
2934 The value to remove.
2935 /
2936
2937Remove the first occurrence of a value in the bytearray.
2938[clinic start generated code]*/
2939
2940PyDoc_STRVAR(bytearray_remove__doc__,
2941"remove($self, value, /)\n"
2942"--\n"
2943"\n"
2944"Remove the first occurrence of a value in the bytearray.\n"
2945"\n"
2946" value\n"
2947" The value to remove.");
2948
2949#define BYTEARRAY_REMOVE_METHODDEF \
2950 {"remove", (PyCFunction)bytearray_remove, METH_VARARGS, bytearray_remove__doc__},
2951
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002952static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002953bytearray_remove_impl(PyByteArrayObject *self, int value);
2954
2955static PyObject *
2956bytearray_remove(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002957{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002958 PyObject *return_value = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002959 int value;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002960
2961 if (!PyArg_ParseTuple(args,
2962 "O&:remove",
2963 _getbytevalue, &value))
2964 goto exit;
2965 return_value = bytearray_remove_impl(self, value);
2966
2967exit:
2968 return return_value;
2969}
2970
2971static PyObject *
2972bytearray_remove_impl(PyByteArrayObject *self, int value)
2973/*[clinic end generated code: output=c71c8bcf4703abfc input=47560b11fd856c24]*/
2974{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002975 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002976 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002977
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002978 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002979 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002980 break;
2981 }
2982 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002983 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002984 return NULL;
2985 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002986 if (!_canresize(self))
2987 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002988
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002989 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002990 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2991 return NULL;
2992
2993 Py_RETURN_NONE;
2994}
2995
2996/* XXX These two helpers could be optimized if argsize == 1 */
2997
2998static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002999lstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003000 void *argptr, Py_ssize_t argsize)
3001{
3002 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02003003 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003004 i++;
3005 return i;
3006}
3007
3008static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02003009rstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003010 void *argptr, Py_ssize_t argsize)
3011{
3012 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02003013 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003014 i--;
3015 return i + 1;
3016}
3017
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003018/*[clinic input]
3019bytearray.strip
3020
3021 bytes: object = None
3022 /
3023
3024Strip leading and trailing bytes contained in the argument.
3025
3026If the argument is omitted or None, strip leading and trailing ASCII whitespace.
3027[clinic start generated code]*/
3028
3029PyDoc_STRVAR(bytearray_strip__doc__,
3030"strip($self, bytes=None, /)\n"
3031"--\n"
3032"\n"
3033"Strip leading and trailing bytes contained in the argument.\n"
3034"\n"
3035"If the argument is omitted or None, strip leading and trailing ASCII whitespace.");
3036
3037#define BYTEARRAY_STRIP_METHODDEF \
3038 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, bytearray_strip__doc__},
3039
3040static PyObject *
3041bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes);
3042
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003043static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003044bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003045{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003046 PyObject *return_value = NULL;
3047 PyObject *bytes = Py_None;
3048
3049 if (!PyArg_UnpackTuple(args, "strip",
3050 0, 1,
3051 &bytes))
3052 goto exit;
3053 return_value = bytearray_strip_impl(self, bytes);
3054
3055exit:
3056 return return_value;
3057}
3058
3059static PyObject *
3060bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
3061/*[clinic end generated code: output=2e3d3358acc4c235 input=ef7bb59b09c21d62]*/
3062{
3063 Py_ssize_t left, right, mysize, byteslen;
3064 char *myptr, *bytesptr;
3065 Py_buffer vbytes;
3066
3067 if (bytes == Py_None) {
3068 bytesptr = "\t\n\r\f\v ";
3069 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003070 }
3071 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02003072 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003073 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003074 bytesptr = (char *) vbytes.buf;
3075 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003076 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003077 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003078 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003079 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003080 if (left == mysize)
3081 right = left;
3082 else
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003083 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
3084 if (bytes != Py_None)
3085 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003086 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003087}
3088
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003089/*[clinic input]
3090bytearray.lstrip
3091
3092 bytes: object = None
3093 /
3094
3095Strip leading bytes contained in the argument.
3096
3097If the argument is omitted or None, strip leading ASCII whitespace.
3098[clinic start generated code]*/
3099
3100PyDoc_STRVAR(bytearray_lstrip__doc__,
3101"lstrip($self, bytes=None, /)\n"
3102"--\n"
3103"\n"
3104"Strip leading bytes contained in the argument.\n"
3105"\n"
3106"If the argument is omitted or None, strip leading ASCII whitespace.");
3107
3108#define BYTEARRAY_LSTRIP_METHODDEF \
3109 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, bytearray_lstrip__doc__},
3110
3111static PyObject *
3112bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes);
3113
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003114static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003115bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003116{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003117 PyObject *return_value = NULL;
3118 PyObject *bytes = Py_None;
3119
3120 if (!PyArg_UnpackTuple(args, "lstrip",
3121 0, 1,
3122 &bytes))
3123 goto exit;
3124 return_value = bytearray_lstrip_impl(self, bytes);
3125
3126exit:
3127 return return_value;
3128}
3129
3130static PyObject *
3131bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
3132/*[clinic end generated code: output=2599309808a9ec02 input=80843f975dd7c480]*/
3133{
3134 Py_ssize_t left, right, mysize, byteslen;
3135 char *myptr, *bytesptr;
3136 Py_buffer vbytes;
3137
3138 if (bytes == Py_None) {
3139 bytesptr = "\t\n\r\f\v ";
3140 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003141 }
3142 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02003143 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003144 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003145 bytesptr = (char *) vbytes.buf;
3146 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003147 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003148 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003149 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003150 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003151 right = mysize;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003152 if (bytes != Py_None)
3153 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003154 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003155}
3156
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003157/*[clinic input]
3158bytearray.rstrip
3159
3160 bytes: object = None
3161 /
3162
3163Strip trailing bytes contained in the argument.
3164
3165If the argument is omitted or None, strip trailing ASCII whitespace.
3166[clinic start generated code]*/
3167
3168PyDoc_STRVAR(bytearray_rstrip__doc__,
3169"rstrip($self, bytes=None, /)\n"
3170"--\n"
3171"\n"
3172"Strip trailing bytes contained in the argument.\n"
3173"\n"
3174"If the argument is omitted or None, strip trailing ASCII whitespace.");
3175
3176#define BYTEARRAY_RSTRIP_METHODDEF \
3177 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, bytearray_rstrip__doc__},
3178
3179static PyObject *
3180bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes);
3181
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003182static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003183bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003184{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003185 PyObject *return_value = NULL;
3186 PyObject *bytes = Py_None;
3187
3188 if (!PyArg_UnpackTuple(args, "rstrip",
3189 0, 1,
3190 &bytes))
3191 goto exit;
3192 return_value = bytearray_rstrip_impl(self, bytes);
3193
3194exit:
3195 return return_value;
3196}
3197
3198static PyObject *
3199bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
3200/*[clinic end generated code: output=b5ca6259f4f4f2a3 input=e728b994954cfd91]*/
3201{
3202 Py_ssize_t right, mysize, byteslen;
3203 char *myptr, *bytesptr;
3204 Py_buffer vbytes;
3205
3206 if (bytes == Py_None) {
3207 bytesptr = "\t\n\r\f\v ";
3208 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003209 }
3210 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02003211 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003212 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003213 bytesptr = (char *) vbytes.buf;
3214 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003215 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003216 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003217 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003218 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
3219 if (bytes != Py_None)
3220 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003221 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003222}
3223
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003224/*[clinic input]
3225bytearray.decode
3226
3227 encoding: str(c_default="NULL") = 'utf-8'
3228 The encoding with which to decode the bytearray.
3229 errors: str(c_default="NULL") = 'strict'
3230 The error handling scheme to use for the handling of decoding errors.
3231 The default is 'strict' meaning that decoding errors raise a
3232 UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
3233 as well as any other name registered with codecs.register_error that
3234 can handle UnicodeDecodeErrors.
3235
3236Decode the bytearray using the codec registered for encoding.
3237[clinic start generated code]*/
3238
3239PyDoc_STRVAR(bytearray_decode__doc__,
3240"decode($self, /, encoding=\'utf-8\', errors=\'strict\')\n"
3241"--\n"
3242"\n"
3243"Decode the bytearray using the codec registered for encoding.\n"
3244"\n"
3245" encoding\n"
3246" The encoding with which to decode the bytearray.\n"
3247" errors\n"
3248" The error handling scheme to use for the handling of decoding errors.\n"
3249" The default is \'strict\' meaning that decoding errors raise a\n"
3250" UnicodeDecodeError. Other possible values are \'ignore\' and \'replace\'\n"
3251" as well as any other name registered with codecs.register_error that\n"
3252" can handle UnicodeDecodeErrors.");
3253
3254#define BYTEARRAY_DECODE_METHODDEF \
3255 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS|METH_KEYWORDS, bytearray_decode__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003256
3257static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003258bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, const char *errors);
3259
3260static PyObject *
3261bytearray_decode(PyByteArrayObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003262{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003263 PyObject *return_value = NULL;
3264 static char *_keywords[] = {"encoding", "errors", NULL};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003265 const char *encoding = NULL;
3266 const char *errors = NULL;
3267
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003268 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3269 "|ss:decode", _keywords,
3270 &encoding, &errors))
3271 goto exit;
3272 return_value = bytearray_decode_impl(self, encoding, errors);
3273
3274exit:
3275 return return_value;
3276}
3277
3278static PyObject *
3279bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, const char *errors)
3280/*[clinic end generated code: output=38b83681f1e38a6c input=f28d8f903020257b]*/
3281{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003282 if (encoding == NULL)
3283 encoding = PyUnicode_GetDefaultEncoding();
Martin v. Löwis0efea322014-07-27 17:29:17 +02003284 return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003285}
3286
3287PyDoc_STRVAR(alloc_doc,
3288"B.__alloc__() -> int\n\
3289\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00003290Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003291
3292static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003293bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003294{
3295 return PyLong_FromSsize_t(self->ob_alloc);
3296}
3297
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003298/*[clinic input]
3299bytearray.join
3300
3301 iterable_of_bytes: object
3302 /
3303
3304Concatenate any number of bytes/bytearray objects.
3305
3306The bytearray whose method is called is inserted in between each pair.
3307
3308The result is returned as a new bytearray object.
3309[clinic start generated code]*/
3310
3311PyDoc_STRVAR(bytearray_join__doc__,
3312"join($self, iterable_of_bytes, /)\n"
3313"--\n"
3314"\n"
3315"Concatenate any number of bytes/bytearray objects.\n"
3316"\n"
3317"The bytearray whose method is called is inserted in between each pair.\n"
3318"\n"
3319"The result is returned as a new bytearray object.");
3320
3321#define BYTEARRAY_JOIN_METHODDEF \
3322 {"join", (PyCFunction)bytearray_join, METH_O, bytearray_join__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003323
3324static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003325bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
3326/*[clinic end generated code: output=544e7430032dfdf4 input=aba6b1f9b30fcb8e]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003327{
Martin v. Löwis0efea322014-07-27 17:29:17 +02003328 return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003329}
3330
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003331/*[clinic input]
3332bytearray.splitlines
Antoine Pitrouf2c54842010-01-13 08:07:53 +00003333
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003334 keepends: int(py_default="False") = 0
3335
3336Return a list of the lines in the bytearray, breaking at line boundaries.
3337
3338Line breaks are not included in the resulting list unless keepends is given and
3339true.
3340[clinic start generated code]*/
3341
3342PyDoc_STRVAR(bytearray_splitlines__doc__,
3343"splitlines($self, /, keepends=False)\n"
3344"--\n"
3345"\n"
3346"Return a list of the lines in the bytearray, breaking at line boundaries.\n"
3347"\n"
3348"Line breaks are not included in the resulting list unless keepends is given and\n"
3349"true.");
3350
3351#define BYTEARRAY_SPLITLINES_METHODDEF \
3352 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS|METH_KEYWORDS, bytearray_splitlines__doc__},
3353
3354static PyObject *
3355bytearray_splitlines_impl(PyByteArrayObject *self, int keepends);
3356
3357static PyObject *
3358bytearray_splitlines(PyByteArrayObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00003359{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003360 PyObject *return_value = NULL;
3361 static char *_keywords[] = {"keepends", NULL};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00003362 int keepends = 0;
3363
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003364 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3365 "|i:splitlines", _keywords,
3366 &keepends))
3367 goto exit;
3368 return_value = bytearray_splitlines_impl(self, keepends);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00003369
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003370exit:
3371 return return_value;
3372}
3373
3374static PyObject *
3375bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
3376/*[clinic end generated code: output=a837fd0512ad46ff input=36f0b25bc792f6c0]*/
3377{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00003378 return stringlib_splitlines(
3379 (PyObject*) self, PyByteArray_AS_STRING(self),
3380 PyByteArray_GET_SIZE(self), keepends
3381 );
3382}
3383
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003384static int
Victor Stinner6430fd52011-09-29 04:02:13 +02003385hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003386{
3387 if (c >= 128)
3388 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00003389 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003390 return c - '0';
3391 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00003392 if (Py_ISUPPER(c))
3393 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003394 if (c >= 'a' && c <= 'f')
3395 return c - 'a' + 10;
3396 }
3397 return -1;
3398}
3399
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003400/*[clinic input]
3401@classmethod
3402bytearray.fromhex
3403
3404 cls: self(type="PyObject*")
3405 string: unicode
3406 /
3407
3408Create a bytearray object from a string of hexadecimal numbers.
3409
3410Spaces between two numbers are accepted.
3411Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
3412[clinic start generated code]*/
3413
3414PyDoc_STRVAR(bytearray_fromhex__doc__,
3415"fromhex($type, string, /)\n"
3416"--\n"
3417"\n"
3418"Create a bytearray object from a string of hexadecimal numbers.\n"
3419"\n"
3420"Spaces between two numbers are accepted.\n"
3421"Example: bytearray.fromhex(\'B9 01EF\') -> bytearray(b\'\\\\xb9\\\\x01\\\\xef\')");
3422
3423#define BYTEARRAY_FROMHEX_METHODDEF \
3424 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, bytearray_fromhex__doc__},
3425
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003426static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003427bytearray_fromhex_impl(PyObject*cls, PyObject *string);
3428
3429static PyObject *
3430bytearray_fromhex(PyTypeObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003431{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003432 PyObject *return_value = NULL;
3433 PyObject *string;
3434
3435 if (!PyArg_ParseTuple(args,
3436 "U:fromhex",
3437 &string))
3438 goto exit;
3439 return_value = bytearray_fromhex_impl((PyObject*)cls, string);
3440
3441exit:
3442 return return_value;
3443}
3444
3445static PyObject *
3446bytearray_fromhex_impl(PyObject*cls, PyObject *string)
3447/*[clinic end generated code: output=adc3c804a74e56d4 input=907bbd2d34d9367a]*/
3448{
3449 PyObject *newbytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003450 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003451 Py_ssize_t hexlen, byteslen, i, j;
3452 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003453 void *data;
3454 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003455
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003456 assert(PyUnicode_Check(string));
3457 if (PyUnicode_READY(string))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003458 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003459 kind = PyUnicode_KIND(string);
3460 data = PyUnicode_DATA(string);
3461 hexlen = PyUnicode_GET_LENGTH(string);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003462
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003463 byteslen = hexlen/2; /* This overestimates if there are spaces */
3464 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
3465 if (!newbytes)
3466 return NULL;
3467 buf = PyByteArray_AS_STRING(newbytes);
3468 for (i = j = 0; i < hexlen; i += 2) {
3469 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003470 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003471 i++;
3472 if (i >= hexlen)
3473 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003474 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
3475 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003476 if (top == -1 || bot == -1) {
3477 PyErr_Format(PyExc_ValueError,
3478 "non-hexadecimal number found in "
3479 "fromhex() arg at position %zd", i);
3480 goto error;
3481 }
3482 buf[j++] = (top << 4) + bot;
3483 }
3484 if (PyByteArray_Resize(newbytes, j) < 0)
3485 goto error;
3486 return newbytes;
3487
3488 error:
3489 Py_DECREF(newbytes);
3490 return NULL;
3491}
3492
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003493
3494static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003495_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003496{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003497 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003498 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003499 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003500
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003501 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003502 if (dict == NULL) {
3503 PyErr_Clear();
3504 dict = Py_None;
3505 Py_INCREF(dict);
3506 }
3507
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003508 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003509 if (proto < 3) {
3510 /* use str based reduction for backwards compatibility with Python 2.x */
3511 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003512 if (Py_SIZE(self))
3513 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003514 else
3515 latin1 = PyUnicode_FromString("");
3516 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
3517 }
3518 else {
3519 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003520 if (Py_SIZE(self)) {
3521 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003522 }
3523 else {
3524 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
3525 }
3526 }
3527}
3528
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003529/*[clinic input]
3530bytearray.__reduce__ as bytearray_reduce
3531
3532 self: self(type="PyByteArrayObject *")
3533
3534Return state information for pickling.
3535[clinic start generated code]*/
3536
3537PyDoc_STRVAR(bytearray_reduce__doc__,
3538"__reduce__($self, /)\n"
3539"--\n"
3540"\n"
3541"Return state information for pickling.");
3542
3543#define BYTEARRAY_REDUCE_METHODDEF \
3544 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, bytearray_reduce__doc__},
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003545
3546static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003547bytearray_reduce_impl(PyByteArrayObject *self);
3548
3549static PyObject *
3550bytearray_reduce(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
3551{
3552 return bytearray_reduce_impl(self);
3553}
3554
3555static PyObject *
3556bytearray_reduce_impl(PyByteArrayObject *self)
3557/*[clinic end generated code: output=b1b56fe87bf30fb0 input=fbb07de4d102a03a]*/
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003558{
3559 return _common_reduce(self, 2);
3560}
3561
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003562/*[clinic input]
3563bytearray.__reduce_ex__ as bytearray_reduce_ex
3564
3565 self: self(type="PyByteArrayObject *")
3566 proto: int = 0
3567 /
3568
3569Return state information for pickling.
3570[clinic start generated code]*/
3571
3572PyDoc_STRVAR(bytearray_reduce_ex__doc__,
3573"__reduce_ex__($self, proto=0, /)\n"
3574"--\n"
3575"\n"
3576"Return state information for pickling.");
3577
3578#define BYTEARRAY_REDUCE_EX_METHODDEF \
3579 {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, bytearray_reduce_ex__doc__},
3580
3581static PyObject *
3582bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003583
3584static PyObject *
3585bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
3586{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003587 PyObject *return_value = NULL;
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003588 int proto = 0;
3589
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003590 if (!PyArg_ParseTuple(args,
3591 "|i:__reduce_ex__",
3592 &proto))
3593 goto exit;
3594 return_value = bytearray_reduce_ex_impl(self, proto);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003595
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003596exit:
3597 return return_value;
3598}
3599
3600static PyObject *
3601bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
3602/*[clinic end generated code: output=bbd9afb2f5953dc1 input=0e091a42ca6dbd91]*/
3603{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003604 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003605}
3606
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003607/*[clinic input]
3608bytearray.__sizeof__ as bytearray_sizeof
3609
3610 self: self(type="PyByteArrayObject *")
3611
3612Returns the size of the bytearray object in memory, in bytes.
3613[clinic start generated code]*/
3614
3615PyDoc_STRVAR(bytearray_sizeof__doc__,
3616"__sizeof__($self, /)\n"
3617"--\n"
3618"\n"
3619"Returns the size of the bytearray object in memory, in bytes.");
3620
3621#define BYTEARRAY_SIZEOF_METHODDEF \
3622 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, bytearray_sizeof__doc__},
3623
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003624static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003625bytearray_sizeof_impl(PyByteArrayObject *self);
3626
3627static PyObject *
3628bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
3629{
3630 return bytearray_sizeof_impl(self);
3631}
3632
3633static PyObject *
3634bytearray_sizeof_impl(PyByteArrayObject *self)
3635/*[clinic end generated code: output=4a2254b0a85630c6 input=6b23d305362b462b]*/
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003636{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00003637 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003638
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00003639 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
3640 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003641}
3642
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003643static PySequenceMethods bytearray_as_sequence = {
3644 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003645 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003646 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
3647 (ssizeargfunc)bytearray_getitem, /* sq_item */
3648 0, /* sq_slice */
3649 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
3650 0, /* sq_ass_slice */
3651 (objobjproc)bytearray_contains, /* sq_contains */
3652 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
3653 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003654};
3655
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003656static PyMappingMethods bytearray_as_mapping = {
3657 (lenfunc)bytearray_length,
3658 (binaryfunc)bytearray_subscript,
3659 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003660};
3661
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003662static PyBufferProcs bytearray_as_buffer = {
3663 (getbufferproc)bytearray_getbuffer,
3664 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003665};
3666
3667static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003668bytearray_methods[] = {
3669 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003670 BYTEARRAY_REDUCE_METHODDEF
3671 BYTEARRAY_REDUCE_EX_METHODDEF
3672 BYTEARRAY_SIZEOF_METHODDEF
3673 BYTEARRAY_APPEND_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003674 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
3675 _Py_capitalize__doc__},
3676 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003677 BYTEARRAY_CLEAR_METHODDEF
3678 BYTEARRAY_COPY_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003679 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003680 BYTEARRAY_DECODE_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003681 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Ezio Melotti745d54d2013-11-16 19:10:57 +02003682 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003683 expandtabs__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003684 BYTEARRAY_EXTEND_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003685 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003686 BYTEARRAY_FROMHEX_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003687 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003688 BYTEARRAY_INSERT_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003689 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
3690 _Py_isalnum__doc__},
3691 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
3692 _Py_isalpha__doc__},
3693 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
3694 _Py_isdigit__doc__},
3695 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
3696 _Py_islower__doc__},
3697 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
3698 _Py_isspace__doc__},
3699 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
3700 _Py_istitle__doc__},
3701 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
3702 _Py_isupper__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003703 BYTEARRAY_JOIN_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003704 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
3705 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003706 BYTEARRAY_LSTRIP_METHODDEF
3707 BYTEARRAY_MAKETRANS_METHODDEF
3708 BYTEARRAY_PARTITION_METHODDEF
3709 BYTEARRAY_POP_METHODDEF
3710 BYTEARRAY_REMOVE_METHODDEF
3711 BYTEARRAY_REPLACE_METHODDEF
3712 BYTEARRAY_REVERSE_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003713 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
3714 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003715 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003716 BYTEARRAY_RPARTITION_METHODDEF
3717 BYTEARRAY_RSPLIT_METHODDEF
3718 BYTEARRAY_RSTRIP_METHODDEF
3719 BYTEARRAY_SPLIT_METHODDEF
3720 BYTEARRAY_SPLITLINES_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003721 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003722 startswith__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003723 BYTEARRAY_STRIP_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003724 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
3725 _Py_swapcase__doc__},
3726 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003727 BYTEARRAY_TRANSLATE_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003728 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
3729 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
3730 {NULL}
3731};
3732
Ethan Furmanb95b5612015-01-23 20:05:18 -08003733static PyObject *
3734bytearray_mod(PyObject *v, PyObject *w)
3735{
3736 if (!PyByteArray_Check(v))
3737 Py_RETURN_NOTIMPLEMENTED;
3738 return bytearray_format((PyByteArrayObject *)v, w);
3739}
3740
3741static PyNumberMethods bytearray_as_number = {
3742 0, /*nb_add*/
3743 0, /*nb_subtract*/
3744 0, /*nb_multiply*/
3745 bytearray_mod, /*nb_remainder*/
3746};
3747
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003748PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00003749"bytearray(iterable_of_ints) -> bytearray\n\
3750bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003751bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
3752bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
3753bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003754\n\
3755Construct an mutable bytearray object from:\n\
3756 - an iterable yielding integers in range(256)\n\
3757 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003758 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003759 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003760 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003761
3762
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003763static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003764
3765PyTypeObject PyByteArray_Type = {
3766 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3767 "bytearray",
3768 sizeof(PyByteArrayObject),
3769 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003770 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003771 0, /* tp_print */
3772 0, /* tp_getattr */
3773 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003774 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003775 (reprfunc)bytearray_repr, /* tp_repr */
Ethan Furmanb95b5612015-01-23 20:05:18 -08003776 &bytearray_as_number, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003777 &bytearray_as_sequence, /* tp_as_sequence */
3778 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003779 0, /* tp_hash */
3780 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003781 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003782 PyObject_GenericGetAttr, /* tp_getattro */
3783 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003784 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003785 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003786 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003787 0, /* tp_traverse */
3788 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003789 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003790 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003791 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003792 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003793 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003794 0, /* tp_members */
3795 0, /* tp_getset */
3796 0, /* tp_base */
3797 0, /* tp_dict */
3798 0, /* tp_descr_get */
3799 0, /* tp_descr_set */
3800 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003801 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003802 PyType_GenericAlloc, /* tp_alloc */
3803 PyType_GenericNew, /* tp_new */
3804 PyObject_Del, /* tp_free */
3805};
3806
3807/*********************** Bytes Iterator ****************************/
3808
3809typedef struct {
3810 PyObject_HEAD
3811 Py_ssize_t it_index;
3812 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
3813} bytesiterobject;
3814
3815static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003816bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003817{
3818 _PyObject_GC_UNTRACK(it);
3819 Py_XDECREF(it->it_seq);
3820 PyObject_GC_Del(it);
3821}
3822
3823static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003824bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003825{
3826 Py_VISIT(it->it_seq);
3827 return 0;
3828}
3829
3830static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003831bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003832{
3833 PyByteArrayObject *seq;
3834 PyObject *item;
3835
3836 assert(it != NULL);
3837 seq = it->it_seq;
3838 if (seq == NULL)
3839 return NULL;
3840 assert(PyByteArray_Check(seq));
3841
3842 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
3843 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003844 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003845 if (item != NULL)
3846 ++it->it_index;
3847 return item;
3848 }
3849
3850 Py_DECREF(seq);
3851 it->it_seq = NULL;
3852 return NULL;
3853}
3854
3855static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003856bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003857{
3858 Py_ssize_t len = 0;
3859 if (it->it_seq)
3860 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3861 return PyLong_FromSsize_t(len);
3862}
3863
3864PyDoc_STRVAR(length_hint_doc,
3865 "Private method returning an estimate of len(list(it)).");
3866
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003867static PyObject *
3868bytearrayiter_reduce(bytesiterobject *it)
3869{
3870 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02003871 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003872 it->it_seq, it->it_index);
3873 } else {
3874 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
3875 if (u == NULL)
3876 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02003877 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003878 }
3879}
3880
3881static PyObject *
3882bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3883{
3884 Py_ssize_t index = PyLong_AsSsize_t(state);
3885 if (index == -1 && PyErr_Occurred())
3886 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +00003887 if (it->it_seq != NULL) {
3888 if (index < 0)
3889 index = 0;
3890 else if (index > PyByteArray_GET_SIZE(it->it_seq))
3891 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
3892 it->it_index = index;
3893 }
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003894 Py_RETURN_NONE;
3895}
3896
3897PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3898
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003899static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003900 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003901 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003902 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003903 bytearray_reduce__doc__},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003904 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3905 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003906 {NULL, NULL} /* sentinel */
3907};
3908
3909PyTypeObject PyByteArrayIter_Type = {
3910 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3911 "bytearray_iterator", /* tp_name */
3912 sizeof(bytesiterobject), /* tp_basicsize */
3913 0, /* tp_itemsize */
3914 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003915 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003916 0, /* tp_print */
3917 0, /* tp_getattr */
3918 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003919 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003920 0, /* tp_repr */
3921 0, /* tp_as_number */
3922 0, /* tp_as_sequence */
3923 0, /* tp_as_mapping */
3924 0, /* tp_hash */
3925 0, /* tp_call */
3926 0, /* tp_str */
3927 PyObject_GenericGetAttr, /* tp_getattro */
3928 0, /* tp_setattro */
3929 0, /* tp_as_buffer */
3930 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3931 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003932 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003933 0, /* tp_clear */
3934 0, /* tp_richcompare */
3935 0, /* tp_weaklistoffset */
3936 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003937 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3938 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003939 0,
3940};
3941
3942static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003943bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003944{
3945 bytesiterobject *it;
3946
3947 if (!PyByteArray_Check(seq)) {
3948 PyErr_BadInternalCall();
3949 return NULL;
3950 }
3951 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3952 if (it == NULL)
3953 return NULL;
3954 it->it_index = 0;
3955 Py_INCREF(seq);
3956 it->it_seq = (PyByteArrayObject *)seq;
3957 _PyObject_GC_TRACK(it);
3958 return (PyObject *)it;
3959}