blob: 1dce4c7ff61266efc902d9451eb40fb1a1b277e3 [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
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030093#include "clinic/bytearrayobject.c.h"
94
Christian Heimes2c9c7a52008-05-26 13:42:13 +000095/* Direct API functions */
96
97PyObject *
98PyByteArray_FromObject(PyObject *input)
99{
100 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
101 input, NULL);
102}
103
104PyObject *
105PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
106{
107 PyByteArrayObject *new;
108 Py_ssize_t alloc;
109
110 if (size < 0) {
111 PyErr_SetString(PyExc_SystemError,
112 "Negative size passed to PyByteArray_FromStringAndSize");
113 return NULL;
114 }
115
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000116 /* Prevent buffer overflow when setting alloc to size+1. */
117 if (size == PY_SSIZE_T_MAX) {
118 return PyErr_NoMemory();
119 }
120
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000121 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
122 if (new == NULL)
123 return NULL;
124
125 if (size == 0) {
126 new->ob_bytes = NULL;
127 alloc = 0;
128 }
129 else {
130 alloc = size + 1;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100131 new->ob_bytes = PyObject_Malloc(alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000132 if (new->ob_bytes == NULL) {
133 Py_DECREF(new);
134 return PyErr_NoMemory();
135 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +0000136 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000137 memcpy(new->ob_bytes, bytes, size);
138 new->ob_bytes[size] = '\0'; /* Trailing null byte */
139 }
140 Py_SIZE(new) = size;
141 new->ob_alloc = alloc;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200142 new->ob_start = new->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000143 new->ob_exports = 0;
144
145 return (PyObject *)new;
146}
147
148Py_ssize_t
149PyByteArray_Size(PyObject *self)
150{
151 assert(self != NULL);
152 assert(PyByteArray_Check(self));
153
154 return PyByteArray_GET_SIZE(self);
155}
156
157char *
158PyByteArray_AsString(PyObject *self)
159{
160 assert(self != NULL);
161 assert(PyByteArray_Check(self));
162
163 return PyByteArray_AS_STRING(self);
164}
165
166int
Antoine Pitroucc231542014-11-02 18:40:09 +0100167PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000168{
169 void *sval;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200170 PyByteArrayObject *obj = ((PyByteArrayObject *)self);
Antoine Pitroucc231542014-11-02 18:40:09 +0100171 /* All computations are done unsigned to avoid integer overflows
172 (see issue #22335). */
173 size_t alloc = (size_t) obj->ob_alloc;
174 size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
175 size_t size = (size_t) requested_size;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000176
177 assert(self != NULL);
178 assert(PyByteArray_Check(self));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200179 assert(logical_offset <= alloc);
Antoine Pitroucc231542014-11-02 18:40:09 +0100180 assert(requested_size >= 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000181
Antoine Pitroucc231542014-11-02 18:40:09 +0100182 if (requested_size == Py_SIZE(self)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000183 return 0;
184 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200185 if (!_canresize(obj)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000186 return -1;
187 }
188
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200189 if (size + logical_offset + 1 < alloc) {
190 /* Current buffer is large enough to host the requested size,
191 decide on a strategy. */
192 if (size < alloc / 2) {
193 /* Major downsize; resize down to exact size */
194 alloc = size + 1;
195 }
196 else {
197 /* Minor downsize; quick exit */
198 Py_SIZE(self) = size;
199 PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
200 return 0;
201 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000202 }
203 else {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200204 /* Need growing, decide on a strategy */
205 if (size <= alloc * 1.125) {
206 /* Moderate upsize; overallocate similar to list_resize() */
207 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
208 }
209 else {
210 /* Major upsize; resize up to exact size */
211 alloc = size + 1;
212 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000213 }
Antoine Pitroucc231542014-11-02 18:40:09 +0100214 if (alloc > PY_SSIZE_T_MAX) {
215 PyErr_NoMemory();
216 return -1;
217 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000218
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200219 if (logical_offset > 0) {
220 sval = PyObject_Malloc(alloc);
221 if (sval == NULL) {
222 PyErr_NoMemory();
223 return -1;
224 }
Antoine Pitroucc231542014-11-02 18:40:09 +0100225 memcpy(sval, PyByteArray_AS_STRING(self),
226 Py_MIN(requested_size, Py_SIZE(self)));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200227 PyObject_Free(obj->ob_bytes);
228 }
229 else {
230 sval = PyObject_Realloc(obj->ob_bytes, alloc);
231 if (sval == NULL) {
232 PyErr_NoMemory();
233 return -1;
234 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000235 }
236
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200237 obj->ob_bytes = obj->ob_start = sval;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000238 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200239 obj->ob_alloc = alloc;
240 obj->ob_bytes[size] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000241
242 return 0;
243}
244
245PyObject *
246PyByteArray_Concat(PyObject *a, PyObject *b)
247{
248 Py_ssize_t size;
249 Py_buffer va, vb;
250 PyByteArrayObject *result = NULL;
251
252 va.len = -1;
253 vb.len = -1;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200254 if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
255 PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000256 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
257 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
258 goto done;
259 }
260
261 size = va.len + vb.len;
262 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000263 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000264 goto done;
265 }
266
267 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
268 if (result != NULL) {
269 memcpy(result->ob_bytes, va.buf, va.len);
270 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
271 }
272
273 done:
274 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000275 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000276 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000277 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000278 return (PyObject *)result;
279}
280
Ethan Furmanb95b5612015-01-23 20:05:18 -0800281static PyObject *
282bytearray_format(PyByteArrayObject *self, PyObject *args)
283{
284 PyObject *bytes_in, *bytes_out, *res;
285 char *bytestring;
286
287 if (self == NULL || !PyByteArray_Check(self) || args == NULL) {
288 PyErr_BadInternalCall();
289 return NULL;
290 }
291 bytestring = PyByteArray_AS_STRING(self);
292 bytes_in = PyBytes_FromString(bytestring);
293 if (bytes_in == NULL)
294 return NULL;
295 bytes_out = _PyBytes_Format(bytes_in, args);
296 Py_DECREF(bytes_in);
297 if (bytes_out == NULL)
298 return NULL;
299 res = PyByteArray_FromObject(bytes_out);
300 Py_DECREF(bytes_out);
301 if (res == NULL)
302 return NULL;
303 return res;
304}
305
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000306/* Functions stuffed into the type object */
307
308static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000309bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000310{
311 return Py_SIZE(self);
312}
313
314static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000315bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000316{
317 Py_ssize_t mysize;
318 Py_ssize_t size;
319 Py_buffer vo;
320
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200321 if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000322 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
323 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
324 return NULL;
325 }
326
327 mysize = Py_SIZE(self);
328 size = mysize + vo.len;
329 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000330 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000331 return PyErr_NoMemory();
332 }
333 if (size < self->ob_alloc) {
334 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200335 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000336 }
337 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000338 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000339 return NULL;
340 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200341 memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000342 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000343 Py_INCREF(self);
344 return (PyObject *)self;
345}
346
347static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000348bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000349{
350 PyByteArrayObject *result;
351 Py_ssize_t mysize;
352 Py_ssize_t size;
353
354 if (count < 0)
355 count = 0;
356 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000357 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000358 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000359 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000360 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
361 if (result != NULL && size != 0) {
362 if (mysize == 1)
363 memset(result->ob_bytes, self->ob_bytes[0], size);
364 else {
365 Py_ssize_t i;
366 for (i = 0; i < count; i++)
367 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
368 }
369 }
370 return (PyObject *)result;
371}
372
373static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000374bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000375{
376 Py_ssize_t mysize;
377 Py_ssize_t size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200378 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000379
380 if (count < 0)
381 count = 0;
382 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000383 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000384 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000385 size = mysize * count;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200386 if (PyByteArray_Resize((PyObject *)self, size) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000387 return NULL;
388
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200389 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000390 if (mysize == 1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200391 memset(buf, buf[0], size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000392 else {
393 Py_ssize_t i;
394 for (i = 1; i < count; i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200395 memcpy(buf + i*mysize, buf, mysize);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000396 }
397
398 Py_INCREF(self);
399 return (PyObject *)self;
400}
401
402static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000403bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000404{
405 if (i < 0)
406 i += Py_SIZE(self);
407 if (i < 0 || i >= Py_SIZE(self)) {
408 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
409 return NULL;
410 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200411 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000412}
413
414static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000415bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000416{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000417 if (PyIndex_Check(index)) {
418 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000419
420 if (i == -1 && PyErr_Occurred())
421 return NULL;
422
423 if (i < 0)
424 i += PyByteArray_GET_SIZE(self);
425
426 if (i < 0 || i >= Py_SIZE(self)) {
427 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
428 return NULL;
429 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200430 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000431 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000432 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000433 Py_ssize_t start, stop, step, slicelength, cur, i;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000434 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000435 PyByteArray_GET_SIZE(self),
436 &start, &stop, &step, &slicelength) < 0) {
437 return NULL;
438 }
439
440 if (slicelength <= 0)
441 return PyByteArray_FromStringAndSize("", 0);
442 else if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200443 return PyByteArray_FromStringAndSize(
444 PyByteArray_AS_STRING(self) + start, slicelength);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000445 }
446 else {
447 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000448 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000449 PyObject *result;
450
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000451 result = PyByteArray_FromStringAndSize(NULL, slicelength);
452 if (result == NULL)
453 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000454
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000455 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000456 for (cur = start, i = 0; i < slicelength;
457 cur += step, i++) {
458 result_buf[i] = source_buf[cur];
459 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000460 return result;
461 }
462 }
463 else {
Terry Jan Reedyffff1442014-08-02 01:30:37 -0400464 PyErr_Format(PyExc_TypeError,
465 "bytearray indices must be integers or slices, not %.200s",
466 Py_TYPE(index)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000467 return NULL;
468 }
469}
470
471static int
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200472bytearray_setslice_linear(PyByteArrayObject *self,
473 Py_ssize_t lo, Py_ssize_t hi,
474 char *bytes, Py_ssize_t bytes_len)
475{
476 Py_ssize_t avail = hi - lo;
477 char *buf = PyByteArray_AS_STRING(self);
478 Py_ssize_t growth = bytes_len - avail;
Victor Stinner84557232013-11-21 12:29:51 +0100479 int res = 0;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200480 assert(avail >= 0);
481
Victor Stinner84557232013-11-21 12:29:51 +0100482 if (growth < 0) {
483 if (!_canresize(self))
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200484 return -1;
Victor Stinner84557232013-11-21 12:29:51 +0100485
486 if (lo == 0) {
487 /* Shrink the buffer by advancing its logical start */
488 self->ob_start -= growth;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200489 /*
Victor Stinner84557232013-11-21 12:29:51 +0100490 0 lo hi old_size
491 | |<----avail----->|<-----tail------>|
492 | |<-bytes_len->|<-----tail------>|
493 0 new_lo new_hi new_size
494 */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200495 }
Victor Stinner84557232013-11-21 12:29:51 +0100496 else {
497 /*
498 0 lo hi old_size
499 | |<----avail----->|<-----tomove------>|
500 | |<-bytes_len->|<-----tomove------>|
501 0 lo new_hi new_size
502 */
503 memmove(buf + lo + bytes_len, buf + hi,
504 Py_SIZE(self) - hi);
505 }
506 if (PyByteArray_Resize((PyObject *)self,
507 Py_SIZE(self) + growth) < 0) {
508 /* Issue #19578: Handling the memory allocation failure here is
509 tricky here because the bytearray object has already been
510 modified. Depending on growth and lo, the behaviour is
511 different.
512
513 If growth < 0 and lo != 0, the operation is completed, but a
514 MemoryError is still raised and the memory block is not
515 shrinked. Otherwise, the bytearray is restored in its previous
516 state and a MemoryError is raised. */
517 if (lo == 0) {
518 self->ob_start += growth;
519 return -1;
520 }
521 /* memmove() removed bytes, the bytearray object cannot be
522 restored in its previous state. */
523 Py_SIZE(self) += growth;
524 res = -1;
525 }
526 buf = PyByteArray_AS_STRING(self);
527 }
528 else if (growth > 0) {
529 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
530 PyErr_NoMemory();
531 return -1;
532 }
533
534 if (PyByteArray_Resize((PyObject *)self,
535 Py_SIZE(self) + growth) < 0) {
536 return -1;
537 }
538 buf = PyByteArray_AS_STRING(self);
539 /* Make the place for the additional bytes */
540 /*
541 0 lo hi old_size
542 | |<-avail->|<-----tomove------>|
543 | |<---bytes_len-->|<-----tomove------>|
544 0 lo new_hi new_size
545 */
546 memmove(buf + lo + bytes_len, buf + hi,
547 Py_SIZE(self) - lo - bytes_len);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200548 }
549
550 if (bytes_len > 0)
551 memcpy(buf + lo, bytes, bytes_len);
Victor Stinner84557232013-11-21 12:29:51 +0100552 return res;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200553}
554
555static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000556bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000557 PyObject *values)
558{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200559 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000560 void *bytes;
561 Py_buffer vbytes;
562 int res = 0;
563
564 vbytes.len = -1;
565 if (values == (PyObject *)self) {
566 /* Make a copy and call this function recursively */
567 int err;
568 values = PyByteArray_FromObject(values);
569 if (values == NULL)
570 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000571 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000572 Py_DECREF(values);
573 return err;
574 }
575 if (values == NULL) {
576 /* del b[lo:hi] */
577 bytes = NULL;
578 needed = 0;
579 }
580 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200581 if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
582 PyErr_Format(PyExc_TypeError,
583 "can't set bytearray slice from %.100s",
584 Py_TYPE(values)->tp_name);
585 return -1;
586 }
587 needed = vbytes.len;
588 bytes = vbytes.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000589 }
590
591 if (lo < 0)
592 lo = 0;
593 if (hi < lo)
594 hi = lo;
595 if (hi > Py_SIZE(self))
596 hi = Py_SIZE(self);
597
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200598 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000599 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200600 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000601 return res;
602}
603
604static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000605bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000606{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000607 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000608
609 if (i < 0)
610 i += Py_SIZE(self);
611
612 if (i < 0 || i >= Py_SIZE(self)) {
613 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
614 return -1;
615 }
616
617 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000618 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000619
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000620 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000621 return -1;
622
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200623 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000624 return 0;
625}
626
627static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000628bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000629{
630 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200631 char *buf, *bytes;
632 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000633
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000634 if (PyIndex_Check(index)) {
635 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000636
637 if (i == -1 && PyErr_Occurred())
638 return -1;
639
640 if (i < 0)
641 i += PyByteArray_GET_SIZE(self);
642
643 if (i < 0 || i >= Py_SIZE(self)) {
644 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
645 return -1;
646 }
647
648 if (values == NULL) {
649 /* Fall through to slice assignment */
650 start = i;
651 stop = i + 1;
652 step = 1;
653 slicelen = 1;
654 }
655 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000656 int ival;
657 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000658 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200659 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000660 return 0;
661 }
662 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000663 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000664 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000665 PyByteArray_GET_SIZE(self),
666 &start, &stop, &step, &slicelen) < 0) {
667 return -1;
668 }
669 }
670 else {
Terry Jan Reedyffff1442014-08-02 01:30:37 -0400671 PyErr_Format(PyExc_TypeError,
672 "bytearray indices must be integers or slices, not %.200s",
673 Py_TYPE(index)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000674 return -1;
675 }
676
677 if (values == NULL) {
678 bytes = NULL;
679 needed = 0;
680 }
681 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100682 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200683 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
684 PyErr_SetString(PyExc_TypeError,
685 "can assign only bytes, buffers, or iterables "
686 "of ints in range(0, 256)");
687 return -1;
688 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000689 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000690 values = PyByteArray_FromObject(values);
691 if (values == NULL)
692 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000693 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000694 Py_DECREF(values);
695 return err;
696 }
697 else {
698 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200699 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000700 needed = Py_SIZE(values);
701 }
702 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
703 if ((step < 0 && start < stop) ||
704 (step > 0 && start > stop))
705 stop = start;
706 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200707 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000708 }
709 else {
710 if (needed == 0) {
711 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000712 size_t cur;
713 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000714
Antoine Pitrou5504e892008-12-06 21:27:53 +0000715 if (!_canresize(self))
716 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000717
718 if (slicelen == 0)
719 /* Nothing to do here. */
720 return 0;
721
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000722 if (step < 0) {
723 stop = start + 1;
724 start = stop + step * (slicelen - 1) - 1;
725 step = -step;
726 }
727 for (cur = start, i = 0;
728 i < slicelen; cur += step, i++) {
729 Py_ssize_t lim = step - 1;
730
Mark Dickinson66f575b2010-02-14 12:53:32 +0000731 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000732 lim = PyByteArray_GET_SIZE(self) - cur - 1;
733
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200734 memmove(buf + cur - i,
735 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000736 }
737 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000738 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000739 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200740 memmove(buf + cur - slicelen,
741 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000742 PyByteArray_GET_SIZE(self) - cur);
743 }
744 if (PyByteArray_Resize((PyObject *)self,
745 PyByteArray_GET_SIZE(self) - slicelen) < 0)
746 return -1;
747
748 return 0;
749 }
750 else {
751 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000752 Py_ssize_t i;
753 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000754
755 if (needed != slicelen) {
756 PyErr_Format(PyExc_ValueError,
757 "attempt to assign bytes of size %zd "
758 "to extended slice of size %zd",
759 needed, slicelen);
760 return -1;
761 }
762 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200763 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000764 return 0;
765 }
766 }
767}
768
769static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000770bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000771{
772 static char *kwlist[] = {"source", "encoding", "errors", 0};
773 PyObject *arg = NULL;
774 const char *encoding = NULL;
775 const char *errors = NULL;
776 Py_ssize_t count;
777 PyObject *it;
778 PyObject *(*iternext)(PyObject *);
779
780 if (Py_SIZE(self) != 0) {
781 /* Empty previous contents (yes, do this first of all!) */
782 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
783 return -1;
784 }
785
786 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000787 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000788 &arg, &encoding, &errors))
789 return -1;
790
791 /* Make a quick exit if no first argument */
792 if (arg == NULL) {
793 if (encoding != NULL || errors != NULL) {
794 PyErr_SetString(PyExc_TypeError,
795 "encoding or errors without sequence argument");
796 return -1;
797 }
798 return 0;
799 }
800
801 if (PyUnicode_Check(arg)) {
802 /* Encode via the codec registry */
803 PyObject *encoded, *new;
804 if (encoding == NULL) {
805 PyErr_SetString(PyExc_TypeError,
806 "string argument without an encoding");
807 return -1;
808 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000809 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000810 if (encoded == NULL)
811 return -1;
812 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000813 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000814 Py_DECREF(encoded);
815 if (new == NULL)
816 return -1;
817 Py_DECREF(new);
818 return 0;
819 }
820
821 /* If it's not unicode, there can't be encoding or errors */
822 if (encoding != NULL || errors != NULL) {
823 PyErr_SetString(PyExc_TypeError,
824 "encoding or errors without a string argument");
825 return -1;
826 }
827
828 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000829 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
830 if (count == -1 && PyErr_Occurred()) {
831 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000832 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000833 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000834 }
835 else if (count < 0) {
836 PyErr_SetString(PyExc_ValueError, "negative count");
837 return -1;
838 }
839 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000840 if (count > 0) {
Victor Stinner2bc4d952014-06-02 22:22:42 +0200841 if (PyByteArray_Resize((PyObject *)self, count))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000842 return -1;
Victor Stinner2bc4d952014-06-02 22:22:42 +0200843 memset(PyByteArray_AS_STRING(self), 0, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000844 }
845 return 0;
846 }
847
848 /* Use the buffer API */
849 if (PyObject_CheckBuffer(arg)) {
850 Py_ssize_t size;
851 Py_buffer view;
852 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
853 return -1;
854 size = view.len;
855 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200856 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
857 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200858 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000859 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000860 return 0;
861 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000862 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000863 return -1;
864 }
865
866 /* XXX Optimize this if the arguments is a list, tuple */
867
868 /* Get the iterator */
869 it = PyObject_GetIter(arg);
870 if (it == NULL)
871 return -1;
872 iternext = *Py_TYPE(it)->tp_iternext;
873
874 /* Run the iterator to exhaustion */
875 for (;;) {
876 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000877 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000878
879 /* Get the next item */
880 item = iternext(it);
881 if (item == NULL) {
882 if (PyErr_Occurred()) {
883 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
884 goto error;
885 PyErr_Clear();
886 }
887 break;
888 }
889
890 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000891 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000892 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000893 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000894 goto error;
895
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000896 /* Append the byte */
897 if (Py_SIZE(self) < self->ob_alloc)
898 Py_SIZE(self)++;
899 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
900 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200901 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000902 }
903
904 /* Clean up and return success */
905 Py_DECREF(it);
906 return 0;
907
908 error:
909 /* Error handling when it != NULL */
910 Py_DECREF(it);
911 return -1;
912}
913
914/* Mostly copied from string_repr, but without the
915 "smart quote" functionality. */
916static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000917bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000918{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000919 const char *quote_prefix = "bytearray(b";
920 const char *quote_postfix = ")";
921 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200922 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000923 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000924 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200925 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200926 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200927 char c;
928 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200929 int quote;
930 char *test, *start;
931 char *buffer;
932
933 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000934 PyErr_SetString(PyExc_OverflowError,
935 "bytearray object is too large to make repr");
936 return NULL;
937 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200938
939 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100940 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200941 if (buffer == NULL) {
942 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000943 return NULL;
944 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000945
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200946 /* Figure out which quote to use; single is preferred */
947 quote = '\'';
948 start = PyByteArray_AS_STRING(self);
949 for (test = start; test < start+length; ++test) {
950 if (*test == '"') {
951 quote = '\''; /* back to single */
952 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000953 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200954 else if (*test == '\'')
955 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000956 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200957
958 p = buffer;
959 while (*quote_prefix)
960 *p++ = *quote_prefix++;
961 *p++ = quote;
962
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200963 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200964 for (i = 0; i < length; i++) {
965 /* There's at least enough room for a hex escape
966 and a closing quote. */
967 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200968 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200969 if (c == '\'' || c == '\\')
970 *p++ = '\\', *p++ = c;
971 else if (c == '\t')
972 *p++ = '\\', *p++ = 't';
973 else if (c == '\n')
974 *p++ = '\\', *p++ = 'n';
975 else if (c == '\r')
976 *p++ = '\\', *p++ = 'r';
977 else if (c == 0)
978 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
979 else if (c < ' ' || c >= 0x7f) {
980 *p++ = '\\';
981 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200982 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
983 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200984 }
985 else
986 *p++ = c;
987 }
988 assert(newsize - (p - buffer) >= 1);
989 *p++ = quote;
990 while (*quote_postfix) {
991 *p++ = *quote_postfix++;
992 }
993
994 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100995 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200996 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000997}
998
999static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001000bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001001{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +00001002 if (Py_BytesWarningFlag) {
1003 if (PyErr_WarnEx(PyExc_BytesWarning,
1004 "str() on a bytearray instance", 1))
1005 return NULL;
1006 }
1007 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001008}
1009
1010static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001011bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001012{
1013 Py_ssize_t self_size, other_size;
1014 Py_buffer self_bytes, other_bytes;
1015 PyObject *res;
1016 Py_ssize_t minsize;
1017 int cmp;
1018
1019 /* Bytes can be compared to anything that supports the (binary)
1020 buffer API. Except that a comparison with Unicode is always an
1021 error, even if the comparison is for equality. */
1022 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1023 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +00001024 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001025 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +00001026 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001027 return NULL;
1028 }
1029
Brian Curtindfc80e32011-08-10 20:28:54 -05001030 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001031 }
1032
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001033 if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001034 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -05001035 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001036 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001037 self_size = self_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001038
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001039 if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001040 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001041 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001042 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001043 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001044 other_size = other_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001045
1046 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1047 /* Shortcut: if the lengths differ, the objects differ */
1048 cmp = (op == Py_NE);
1049 }
1050 else {
1051 minsize = self_size;
1052 if (other_size < minsize)
1053 minsize = other_size;
1054
1055 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1056 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1057
1058 if (cmp == 0) {
1059 if (self_size < other_size)
1060 cmp = -1;
1061 else if (self_size > other_size)
1062 cmp = 1;
1063 }
1064
1065 switch (op) {
1066 case Py_LT: cmp = cmp < 0; break;
1067 case Py_LE: cmp = cmp <= 0; break;
1068 case Py_EQ: cmp = cmp == 0; break;
1069 case Py_NE: cmp = cmp != 0; break;
1070 case Py_GT: cmp = cmp > 0; break;
1071 case Py_GE: cmp = cmp >= 0; break;
1072 }
1073 }
1074
1075 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001076 PyBuffer_Release(&self_bytes);
1077 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001078 Py_INCREF(res);
1079 return res;
1080}
1081
1082static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001083bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001084{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001085 if (self->ob_exports > 0) {
1086 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001087 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001088 PyErr_Print();
1089 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001090 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001091 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001092 }
1093 Py_TYPE(self)->tp_free((PyObject *)self);
1094}
1095
1096
1097/* -------------------------------------------------------------------- */
1098/* Methods */
1099
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001100#define FASTSEARCH fastsearch
1101#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001102#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001103#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001104#define STRINGLIB_LEN PyByteArray_GET_SIZE
1105#define STRINGLIB_STR PyByteArray_AS_STRING
1106#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001107#define STRINGLIB_ISSPACE Py_ISSPACE
1108#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001109#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1110#define STRINGLIB_MUTABLE 1
1111
1112#include "stringlib/fastsearch.h"
1113#include "stringlib/count.h"
1114#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001115#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001116#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001117#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001118#include "stringlib/ctype.h"
1119#include "stringlib/transmogrify.h"
1120
1121
1122/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1123were copied from the old char* style string object. */
1124
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001125/* helper macro to fixup start/end slice values */
1126#define ADJUST_INDICES(start, end, len) \
1127 if (end > len) \
1128 end = len; \
1129 else if (end < 0) { \
1130 end += len; \
1131 if (end < 0) \
1132 end = 0; \
1133 } \
1134 if (start < 0) { \
1135 start += len; \
1136 if (start < 0) \
1137 start = 0; \
1138 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001139
1140Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001141bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001142{
1143 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001144 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001145 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001146 const char *sub;
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001147 Py_ssize_t len, sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001148 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1149 Py_ssize_t res;
1150
Antoine Pitrouac65d962011-10-20 23:54:17 +02001151 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1152 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001153 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001154
1155 if (subobj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001156 if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001157 return -2;
1158
1159 sub = subbuf.buf;
1160 sub_len = subbuf.len;
1161 }
1162 else {
1163 sub = &byte;
1164 sub_len = 1;
1165 }
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001166 len = PyByteArray_GET_SIZE(self);
Antoine Pitrouac65d962011-10-20 23:54:17 +02001167
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001168 ADJUST_INDICES(start, end, len);
1169 if (end - start < sub_len)
1170 res = -1;
Victor Stinnerdabbfe72015-03-25 03:16:32 +01001171 /* Issue #23573: FIXME, windows has no memrchr() */
1172 else if (sub_len == 1 && dir > 0) {
Serhiy Storchakad9d769f2015-03-24 21:55:47 +02001173 unsigned char needle = *sub;
1174 int mode = (dir > 0) ? FAST_SEARCH : FAST_RSEARCH;
1175 res = stringlib_fastsearch_memchr_1char(
1176 PyByteArray_AS_STRING(self) + start, end - start,
1177 needle, needle, mode);
1178 if (res >= 0)
1179 res += start;
1180 }
1181 else {
1182 if (dir > 0)
1183 res = stringlib_find_slice(
1184 PyByteArray_AS_STRING(self), len,
1185 sub, sub_len, start, end);
1186 else
1187 res = stringlib_rfind_slice(
1188 PyByteArray_AS_STRING(self), len,
1189 sub, sub_len, start, end);
1190 }
Antoine Pitrouac65d962011-10-20 23:54:17 +02001191
1192 if (subobj)
1193 PyBuffer_Release(&subbuf);
1194
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001195 return res;
1196}
1197
1198PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001199"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001200\n\
1201Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001202such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001203arguments start and end are interpreted as in slice notation.\n\
1204\n\
1205Return -1 on failure.");
1206
1207static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001208bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001209{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001210 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001211 if (result == -2)
1212 return NULL;
1213 return PyLong_FromSsize_t(result);
1214}
1215
1216PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001217"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001218\n\
1219Return the number of non-overlapping occurrences of subsection sub in\n\
1220bytes B[start:end]. Optional arguments start and end are interpreted\n\
1221as in slice notation.");
1222
1223static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001224bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001225{
1226 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001227 const char *str = PyByteArray_AS_STRING(self), *sub;
1228 Py_ssize_t sub_len;
1229 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001230 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001231
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001232 Py_buffer vsub;
1233 PyObject *count_obj;
1234
Antoine Pitrouac65d962011-10-20 23:54:17 +02001235 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1236 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001237 return NULL;
1238
Antoine Pitrouac65d962011-10-20 23:54:17 +02001239 if (sub_obj) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001240 if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
Antoine Pitrouac65d962011-10-20 23:54:17 +02001241 return NULL;
1242
1243 sub = vsub.buf;
1244 sub_len = vsub.len;
1245 }
1246 else {
1247 sub = &byte;
1248 sub_len = 1;
1249 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001250
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001251 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001252
1253 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001254 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001255 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001256
1257 if (sub_obj)
1258 PyBuffer_Release(&vsub);
1259
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001260 return count_obj;
1261}
1262
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001263/*[clinic input]
1264bytearray.clear
1265
1266 self: self(type="PyByteArrayObject *")
1267
1268Remove all items from the bytearray.
1269[clinic start generated code]*/
1270
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001271static PyObject *
1272bytearray_clear_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001273/*[clinic end generated code: output=85c2fe6aede0956c input=e524fd330abcdc18]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001274{
1275 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1276 return NULL;
1277 Py_RETURN_NONE;
1278}
1279
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001280/*[clinic input]
1281bytearray.copy
1282
1283 self: self(type="PyByteArrayObject *")
1284
1285Return a copy of B.
1286[clinic start generated code]*/
1287
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001288static PyObject *
1289bytearray_copy_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001290/*[clinic end generated code: output=68cfbcfed484c132 input=6d5d2975aa0f33f3]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001291{
1292 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1293 PyByteArray_GET_SIZE(self));
1294}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001295
1296PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001297"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001298\n\
1299Like B.find() but raise ValueError when the subsection is not found.");
1300
1301static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001302bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001303{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001304 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001305 if (result == -2)
1306 return NULL;
1307 if (result == -1) {
1308 PyErr_SetString(PyExc_ValueError,
1309 "subsection not found");
1310 return NULL;
1311 }
1312 return PyLong_FromSsize_t(result);
1313}
1314
1315
1316PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001317"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001318\n\
1319Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001320such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001321arguments start and end are interpreted as in slice notation.\n\
1322\n\
1323Return -1 on failure.");
1324
1325static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001326bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001327{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001328 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001329 if (result == -2)
1330 return NULL;
1331 return PyLong_FromSsize_t(result);
1332}
1333
1334
1335PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001336"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001337\n\
1338Like B.rfind() but raise ValueError when the subsection is not found.");
1339
1340static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001341bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001342{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001343 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001344 if (result == -2)
1345 return NULL;
1346 if (result == -1) {
1347 PyErr_SetString(PyExc_ValueError,
1348 "subsection not found");
1349 return NULL;
1350 }
1351 return PyLong_FromSsize_t(result);
1352}
1353
1354
1355static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001356bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001357{
1358 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1359 if (ival == -1 && PyErr_Occurred()) {
1360 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001361 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001362 PyErr_Clear();
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001363 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001364 return -1;
1365 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1366 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001367 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001368 return pos >= 0;
1369 }
1370 if (ival < 0 || ival >= 256) {
1371 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1372 return -1;
1373 }
1374
Antoine Pitrou0010d372010-08-15 17:12:55 +00001375 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001376}
1377
1378
1379/* Matches the end (direction >= 0) or start (direction < 0) of self
1380 * against substr, using the start and end arguments. Returns
1381 * -1 on error, 0 if not found and 1 if found.
1382 */
1383Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001384_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001385 Py_ssize_t end, int direction)
1386{
1387 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1388 const char* str;
1389 Py_buffer vsubstr;
1390 int rv = 0;
1391
1392 str = PyByteArray_AS_STRING(self);
1393
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001394 if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001395 return -1;
1396
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001397 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001398
1399 if (direction < 0) {
1400 /* startswith */
1401 if (start+vsubstr.len > len) {
1402 goto done;
1403 }
1404 } else {
1405 /* endswith */
1406 if (end-start < vsubstr.len || start > len) {
1407 goto done;
1408 }
1409
1410 if (end-vsubstr.len > start)
1411 start = end - vsubstr.len;
1412 }
1413 if (end-start >= vsubstr.len)
1414 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1415
1416done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001417 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001418 return rv;
1419}
1420
1421
1422PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001423"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001424\n\
1425Return True if B starts with the specified prefix, False otherwise.\n\
1426With optional start, test B beginning at that position.\n\
1427With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001428prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001429
1430static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001431bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001432{
1433 Py_ssize_t start = 0;
1434 Py_ssize_t end = PY_SSIZE_T_MAX;
1435 PyObject *subobj;
1436 int result;
1437
Jesus Ceaac451502011-04-20 17:09:23 +02001438 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001439 return NULL;
1440 if (PyTuple_Check(subobj)) {
1441 Py_ssize_t i;
1442 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001443 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001444 PyTuple_GET_ITEM(subobj, i),
1445 start, end, -1);
1446 if (result == -1)
1447 return NULL;
1448 else if (result) {
1449 Py_RETURN_TRUE;
1450 }
1451 }
1452 Py_RETURN_FALSE;
1453 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001454 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001455 if (result == -1) {
1456 if (PyErr_ExceptionMatches(PyExc_TypeError))
1457 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1458 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001459 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001460 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001461 else
1462 return PyBool_FromLong(result);
1463}
1464
1465PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001466"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001467\n\
1468Return True if B ends with the specified suffix, False otherwise.\n\
1469With optional start, test B beginning at that position.\n\
1470With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001471suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001472
1473static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001474bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001475{
1476 Py_ssize_t start = 0;
1477 Py_ssize_t end = PY_SSIZE_T_MAX;
1478 PyObject *subobj;
1479 int result;
1480
Jesus Ceaac451502011-04-20 17:09:23 +02001481 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001482 return NULL;
1483 if (PyTuple_Check(subobj)) {
1484 Py_ssize_t i;
1485 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001486 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001487 PyTuple_GET_ITEM(subobj, i),
1488 start, end, +1);
1489 if (result == -1)
1490 return NULL;
1491 else if (result) {
1492 Py_RETURN_TRUE;
1493 }
1494 }
1495 Py_RETURN_FALSE;
1496 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001497 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001498 if (result == -1) {
1499 if (PyErr_ExceptionMatches(PyExc_TypeError))
1500 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1501 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001502 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001503 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001504 else
1505 return PyBool_FromLong(result);
1506}
1507
1508
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001509/*[clinic input]
1510bytearray.translate
1511
1512 self: self(type="PyByteArrayObject *")
1513 table: object
1514 Translation table, which must be a bytes object of length 256.
1515 [
1516 deletechars: object
1517 ]
1518 /
1519
1520Return a copy with each character mapped by the given translation table.
1521
1522All characters occurring in the optional argument deletechars are removed.
1523The remaining characters are mapped through the given translation table.
1524[clinic start generated code]*/
1525
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001526static PyObject *
1527bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_right_1, PyObject *deletechars)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001528/*[clinic end generated code: output=fa3ea4f9a8d58bc7 input=b749ad85f4860824]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001529{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001530 char *input, *output;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001531 const char *table_chars;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001532 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001533 PyObject *input_obj = (PyObject*)self;
1534 const char *output_start;
1535 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001536 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001537 int trans_table[256];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001538 Py_buffer vtable, vdel;
1539
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001540 if (table == Py_None) {
1541 table_chars = NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001542 table = NULL;
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001543 } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001544 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001545 } else {
1546 if (vtable.len != 256) {
1547 PyErr_SetString(PyExc_ValueError,
1548 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001549 PyBuffer_Release(&vtable);
1550 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001551 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001552 table_chars = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001553 }
1554
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001555 if (deletechars != NULL) {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001556 if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001557 if (table != NULL)
Georg Brandl953152f2009-07-22 12:03:59 +00001558 PyBuffer_Release(&vtable);
1559 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001560 }
1561 }
1562 else {
1563 vdel.buf = NULL;
1564 vdel.len = 0;
1565 }
1566
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001567 inlen = PyByteArray_GET_SIZE(input_obj);
1568 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1569 if (result == NULL)
1570 goto done;
1571 output_start = output = PyByteArray_AsString(result);
1572 input = PyByteArray_AS_STRING(input_obj);
1573
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001574 if (vdel.len == 0 && table_chars != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001575 /* If no deletions are required, use faster code */
1576 for (i = inlen; --i >= 0; ) {
1577 c = Py_CHARMASK(*input++);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001578 *output++ = table_chars[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001579 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001580 goto done;
1581 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001582
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001583 if (table_chars == NULL) {
Georg Brandlccc47b62008-12-28 11:44:14 +00001584 for (i = 0; i < 256; i++)
1585 trans_table[i] = Py_CHARMASK(i);
1586 } else {
1587 for (i = 0; i < 256; i++)
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001588 trans_table[i] = Py_CHARMASK(table_chars[i]);
Georg Brandlccc47b62008-12-28 11:44:14 +00001589 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001590
1591 for (i = 0; i < vdel.len; i++)
1592 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1593
1594 for (i = inlen; --i >= 0; ) {
1595 c = Py_CHARMASK(*input++);
1596 if (trans_table[c] != -1)
1597 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1598 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001599 }
1600 /* Fix the size of the resulting string */
1601 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001602 if (PyByteArray_Resize(result, output - output_start) < 0) {
1603 Py_CLEAR(result);
1604 goto done;
1605 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001606
1607done:
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001608 if (table != NULL)
Georg Brandlccc47b62008-12-28 11:44:14 +00001609 PyBuffer_Release(&vtable);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001610 if (deletechars != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001611 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001612 return result;
1613}
1614
1615
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001616/*[clinic input]
1617
1618@staticmethod
1619bytearray.maketrans
1620
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001621 frm: Py_buffer
1622 to: Py_buffer
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001623 /
1624
1625Return a translation table useable for the bytes or bytearray translate method.
1626
1627The returned table will be one where each byte in frm is mapped to the byte at
1628the same position in to.
1629
1630The bytes objects frm and to must be of the same length.
1631[clinic start generated code]*/
1632
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001633static PyObject *
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001634bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001635/*[clinic end generated code: output=1df267d99f56b15e input=5925a81d2fbbf151]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001636{
1637 return _Py_bytes_maketrans(frm, to);
Georg Brandlabc38772009-04-12 15:51:51 +00001638}
1639
1640
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001641/* find and count characters and substrings */
1642
1643#define findchar(target, target_len, c) \
1644 ((char *)memchr((const void *)(target), c, target_len))
1645
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001646
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001647/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001648Py_LOCAL(PyByteArrayObject *)
1649return_self(PyByteArrayObject *self)
1650{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001651 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001652 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1653 PyByteArray_AS_STRING(self),
1654 PyByteArray_GET_SIZE(self));
1655}
1656
1657Py_LOCAL_INLINE(Py_ssize_t)
1658countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1659{
1660 Py_ssize_t count=0;
1661 const char *start=target;
1662 const char *end=target+target_len;
1663
1664 while ( (start=findchar(start, end-start, c)) != NULL ) {
1665 count++;
1666 if (count >= maxcount)
1667 break;
1668 start += 1;
1669 }
1670 return count;
1671}
1672
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001673
1674/* Algorithms for different cases of string replacement */
1675
1676/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1677Py_LOCAL(PyByteArrayObject *)
1678replace_interleave(PyByteArrayObject *self,
1679 const char *to_s, Py_ssize_t to_len,
1680 Py_ssize_t maxcount)
1681{
1682 char *self_s, *result_s;
1683 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001684 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001685 PyByteArrayObject *result;
1686
1687 self_len = PyByteArray_GET_SIZE(self);
1688
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001689 /* 1 at the end plus 1 after every character;
1690 count = min(maxcount, self_len + 1) */
1691 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001692 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001693 else
1694 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1695 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001696
1697 /* Check for overflow */
1698 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001699 assert(count > 0);
1700 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001701 PyErr_SetString(PyExc_OverflowError,
1702 "replace string is too long");
1703 return NULL;
1704 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001705 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001706
1707 if (! (result = (PyByteArrayObject *)
1708 PyByteArray_FromStringAndSize(NULL, result_len)) )
1709 return NULL;
1710
1711 self_s = PyByteArray_AS_STRING(self);
1712 result_s = PyByteArray_AS_STRING(result);
1713
1714 /* TODO: special case single character, which doesn't need memcpy */
1715
1716 /* Lay the first one down (guaranteed this will occur) */
1717 Py_MEMCPY(result_s, to_s, to_len);
1718 result_s += to_len;
1719 count -= 1;
1720
1721 for (i=0; i<count; i++) {
1722 *result_s++ = *self_s++;
1723 Py_MEMCPY(result_s, to_s, to_len);
1724 result_s += to_len;
1725 }
1726
1727 /* Copy the rest of the original string */
1728 Py_MEMCPY(result_s, self_s, self_len-i);
1729
1730 return result;
1731}
1732
1733/* Special case for deleting a single character */
1734/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1735Py_LOCAL(PyByteArrayObject *)
1736replace_delete_single_character(PyByteArrayObject *self,
1737 char from_c, Py_ssize_t maxcount)
1738{
1739 char *self_s, *result_s;
1740 char *start, *next, *end;
1741 Py_ssize_t self_len, result_len;
1742 Py_ssize_t count;
1743 PyByteArrayObject *result;
1744
1745 self_len = PyByteArray_GET_SIZE(self);
1746 self_s = PyByteArray_AS_STRING(self);
1747
1748 count = countchar(self_s, self_len, from_c, maxcount);
1749 if (count == 0) {
1750 return return_self(self);
1751 }
1752
1753 result_len = self_len - count; /* from_len == 1 */
1754 assert(result_len>=0);
1755
1756 if ( (result = (PyByteArrayObject *)
1757 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1758 return NULL;
1759 result_s = PyByteArray_AS_STRING(result);
1760
1761 start = self_s;
1762 end = self_s + self_len;
1763 while (count-- > 0) {
1764 next = findchar(start, end-start, from_c);
1765 if (next == NULL)
1766 break;
1767 Py_MEMCPY(result_s, start, next-start);
1768 result_s += (next-start);
1769 start = next+1;
1770 }
1771 Py_MEMCPY(result_s, start, end-start);
1772
1773 return result;
1774}
1775
1776/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1777
1778Py_LOCAL(PyByteArrayObject *)
1779replace_delete_substring(PyByteArrayObject *self,
1780 const char *from_s, Py_ssize_t from_len,
1781 Py_ssize_t maxcount)
1782{
1783 char *self_s, *result_s;
1784 char *start, *next, *end;
1785 Py_ssize_t self_len, result_len;
1786 Py_ssize_t count, offset;
1787 PyByteArrayObject *result;
1788
1789 self_len = PyByteArray_GET_SIZE(self);
1790 self_s = PyByteArray_AS_STRING(self);
1791
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001792 count = stringlib_count(self_s, self_len,
1793 from_s, from_len,
1794 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001795
1796 if (count == 0) {
1797 /* no matches */
1798 return return_self(self);
1799 }
1800
1801 result_len = self_len - (count * from_len);
1802 assert (result_len>=0);
1803
1804 if ( (result = (PyByteArrayObject *)
1805 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1806 return NULL;
1807
1808 result_s = PyByteArray_AS_STRING(result);
1809
1810 start = self_s;
1811 end = self_s + self_len;
1812 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001813 offset = stringlib_find(start, end-start,
1814 from_s, from_len,
1815 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001816 if (offset == -1)
1817 break;
1818 next = start + offset;
1819
1820 Py_MEMCPY(result_s, start, next-start);
1821
1822 result_s += (next-start);
1823 start = next+from_len;
1824 }
1825 Py_MEMCPY(result_s, start, end-start);
1826 return result;
1827}
1828
1829/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1830Py_LOCAL(PyByteArrayObject *)
1831replace_single_character_in_place(PyByteArrayObject *self,
1832 char from_c, char to_c,
1833 Py_ssize_t maxcount)
1834{
Antoine Pitroud1188562010-06-09 16:38:55 +00001835 char *self_s, *result_s, *start, *end, *next;
1836 Py_ssize_t self_len;
1837 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001838
Antoine Pitroud1188562010-06-09 16:38:55 +00001839 /* The result string will be the same size */
1840 self_s = PyByteArray_AS_STRING(self);
1841 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001842
Antoine Pitroud1188562010-06-09 16:38:55 +00001843 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001844
Antoine Pitroud1188562010-06-09 16:38:55 +00001845 if (next == NULL) {
1846 /* No matches; return the original bytes */
1847 return return_self(self);
1848 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001849
Antoine Pitroud1188562010-06-09 16:38:55 +00001850 /* Need to make a new bytes */
1851 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1852 if (result == NULL)
1853 return NULL;
1854 result_s = PyByteArray_AS_STRING(result);
1855 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001856
Antoine Pitroud1188562010-06-09 16:38:55 +00001857 /* change everything in-place, starting with this one */
1858 start = result_s + (next-self_s);
1859 *start = to_c;
1860 start++;
1861 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001862
Antoine Pitroud1188562010-06-09 16:38:55 +00001863 while (--maxcount > 0) {
1864 next = findchar(start, end-start, from_c);
1865 if (next == NULL)
1866 break;
1867 *next = to_c;
1868 start = next+1;
1869 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001870
Antoine Pitroud1188562010-06-09 16:38:55 +00001871 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001872}
1873
1874/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1875Py_LOCAL(PyByteArrayObject *)
1876replace_substring_in_place(PyByteArrayObject *self,
1877 const char *from_s, Py_ssize_t from_len,
1878 const char *to_s, Py_ssize_t to_len,
1879 Py_ssize_t maxcount)
1880{
1881 char *result_s, *start, *end;
1882 char *self_s;
1883 Py_ssize_t self_len, offset;
1884 PyByteArrayObject *result;
1885
1886 /* The result bytes will be the same size */
1887
1888 self_s = PyByteArray_AS_STRING(self);
1889 self_len = PyByteArray_GET_SIZE(self);
1890
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001891 offset = stringlib_find(self_s, self_len,
1892 from_s, from_len,
1893 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001894 if (offset == -1) {
1895 /* No matches; return the original bytes */
1896 return return_self(self);
1897 }
1898
1899 /* Need to make a new bytes */
1900 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1901 if (result == NULL)
1902 return NULL;
1903 result_s = PyByteArray_AS_STRING(result);
1904 Py_MEMCPY(result_s, self_s, self_len);
1905
1906 /* change everything in-place, starting with this one */
1907 start = result_s + offset;
1908 Py_MEMCPY(start, to_s, from_len);
1909 start += from_len;
1910 end = result_s + self_len;
1911
1912 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001913 offset = stringlib_find(start, end-start,
1914 from_s, from_len,
1915 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001916 if (offset==-1)
1917 break;
1918 Py_MEMCPY(start+offset, to_s, from_len);
1919 start += offset+from_len;
1920 }
1921
1922 return result;
1923}
1924
1925/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1926Py_LOCAL(PyByteArrayObject *)
1927replace_single_character(PyByteArrayObject *self,
1928 char from_c,
1929 const char *to_s, Py_ssize_t to_len,
1930 Py_ssize_t maxcount)
1931{
1932 char *self_s, *result_s;
1933 char *start, *next, *end;
1934 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001935 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001936 PyByteArrayObject *result;
1937
1938 self_s = PyByteArray_AS_STRING(self);
1939 self_len = PyByteArray_GET_SIZE(self);
1940
1941 count = countchar(self_s, self_len, from_c, maxcount);
1942 if (count == 0) {
1943 /* no matches, return unchanged */
1944 return return_self(self);
1945 }
1946
1947 /* use the difference between current and new, hence the "-1" */
1948 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001949 assert(count > 0);
1950 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001951 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1952 return NULL;
1953 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001954 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001955
1956 if ( (result = (PyByteArrayObject *)
1957 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1958 return NULL;
1959 result_s = PyByteArray_AS_STRING(result);
1960
1961 start = self_s;
1962 end = self_s + self_len;
1963 while (count-- > 0) {
1964 next = findchar(start, end-start, from_c);
1965 if (next == NULL)
1966 break;
1967
1968 if (next == start) {
1969 /* replace with the 'to' */
1970 Py_MEMCPY(result_s, to_s, to_len);
1971 result_s += to_len;
1972 start += 1;
1973 } else {
1974 /* copy the unchanged old then the 'to' */
1975 Py_MEMCPY(result_s, start, next-start);
1976 result_s += (next-start);
1977 Py_MEMCPY(result_s, to_s, to_len);
1978 result_s += to_len;
1979 start = next+1;
1980 }
1981 }
1982 /* Copy the remainder of the remaining bytes */
1983 Py_MEMCPY(result_s, start, end-start);
1984
1985 return result;
1986}
1987
1988/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1989Py_LOCAL(PyByteArrayObject *)
1990replace_substring(PyByteArrayObject *self,
1991 const char *from_s, Py_ssize_t from_len,
1992 const char *to_s, Py_ssize_t to_len,
1993 Py_ssize_t maxcount)
1994{
1995 char *self_s, *result_s;
1996 char *start, *next, *end;
1997 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001998 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001999 PyByteArrayObject *result;
2000
2001 self_s = PyByteArray_AS_STRING(self);
2002 self_len = PyByteArray_GET_SIZE(self);
2003
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002004 count = stringlib_count(self_s, self_len,
2005 from_s, from_len,
2006 maxcount);
2007
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002008 if (count == 0) {
2009 /* no matches, return unchanged */
2010 return return_self(self);
2011 }
2012
2013 /* Check for overflow */
2014 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002015 assert(count > 0);
2016 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002017 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
2018 return NULL;
2019 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002020 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002021
2022 if ( (result = (PyByteArrayObject *)
2023 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
2024 return NULL;
2025 result_s = PyByteArray_AS_STRING(result);
2026
2027 start = self_s;
2028 end = self_s + self_len;
2029 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002030 offset = stringlib_find(start, end-start,
2031 from_s, from_len,
2032 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002033 if (offset == -1)
2034 break;
2035 next = start+offset;
2036 if (next == start) {
2037 /* replace with the 'to' */
2038 Py_MEMCPY(result_s, to_s, to_len);
2039 result_s += to_len;
2040 start += from_len;
2041 } else {
2042 /* copy the unchanged old then the 'to' */
2043 Py_MEMCPY(result_s, start, next-start);
2044 result_s += (next-start);
2045 Py_MEMCPY(result_s, to_s, to_len);
2046 result_s += to_len;
2047 start = next+from_len;
2048 }
2049 }
2050 /* Copy the remainder of the remaining bytes */
2051 Py_MEMCPY(result_s, start, end-start);
2052
2053 return result;
2054}
2055
2056
2057Py_LOCAL(PyByteArrayObject *)
2058replace(PyByteArrayObject *self,
2059 const char *from_s, Py_ssize_t from_len,
2060 const char *to_s, Py_ssize_t to_len,
2061 Py_ssize_t maxcount)
2062{
2063 if (maxcount < 0) {
2064 maxcount = PY_SSIZE_T_MAX;
2065 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
2066 /* nothing to do; return the original bytes */
2067 return return_self(self);
2068 }
2069
2070 if (maxcount == 0 ||
2071 (from_len == 0 && to_len == 0)) {
2072 /* nothing to do; return the original bytes */
2073 return return_self(self);
2074 }
2075
2076 /* Handle zero-length special cases */
2077
2078 if (from_len == 0) {
2079 /* insert the 'to' bytes everywhere. */
2080 /* >>> "Python".replace("", ".") */
2081 /* '.P.y.t.h.o.n.' */
2082 return replace_interleave(self, to_s, to_len, maxcount);
2083 }
2084
2085 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2086 /* point for an empty self bytes to generate a non-empty bytes */
2087 /* Special case so the remaining code always gets a non-empty bytes */
2088 if (PyByteArray_GET_SIZE(self) == 0) {
2089 return return_self(self);
2090 }
2091
2092 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002093 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002094 if (from_len == 1) {
2095 return replace_delete_single_character(
2096 self, from_s[0], maxcount);
2097 } else {
2098 return replace_delete_substring(self, from_s, from_len, maxcount);
2099 }
2100 }
2101
2102 /* Handle special case where both bytes have the same length */
2103
2104 if (from_len == to_len) {
2105 if (from_len == 1) {
2106 return replace_single_character_in_place(
2107 self,
2108 from_s[0],
2109 to_s[0],
2110 maxcount);
2111 } else {
2112 return replace_substring_in_place(
2113 self, from_s, from_len, to_s, to_len, maxcount);
2114 }
2115 }
2116
2117 /* Otherwise use the more generic algorithms */
2118 if (from_len == 1) {
2119 return replace_single_character(self, from_s[0],
2120 to_s, to_len, maxcount);
2121 } else {
2122 /* len('from')>=2, len('to')>=1 */
2123 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2124 }
2125}
2126
2127
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002128/*[clinic input]
2129bytearray.replace
2130
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002131 old: Py_buffer
2132 new: Py_buffer
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002133 count: Py_ssize_t = -1
2134 Maximum number of occurrences to replace.
2135 -1 (the default value) means replace all occurrences.
2136 /
2137
2138Return a copy with all occurrences of substring old replaced by new.
2139
2140If the optional argument count is given, only the first count occurrences are
2141replaced.
2142[clinic start generated code]*/
2143
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002144static PyObject *
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002145bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old, Py_buffer *new, Py_ssize_t count)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002146/*[clinic end generated code: output=3fc105c8232d7b3f input=aa379d988637c7fb]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002147{
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002148 return (PyObject *)replace((PyByteArrayObject *) self,
2149 old->buf, old->len,
2150 new->buf, new->len, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002151}
2152
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002153/*[clinic input]
2154bytearray.split
2155
2156 sep: object = None
2157 The delimiter according which to split the bytearray.
2158 None (the default value) means split on ASCII whitespace characters
2159 (space, tab, return, newline, formfeed, vertical tab).
2160 maxsplit: Py_ssize_t = -1
2161 Maximum number of splits to do.
2162 -1 (the default value) means no limit.
2163
2164Return a list of the sections in the bytearray, using sep as the delimiter.
2165[clinic start generated code]*/
2166
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002167static PyObject *
2168bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002169/*[clinic end generated code: output=cdccf5a29dbf7eb5 input=24f82669f41bf523]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002170{
2171 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002172 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002173 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002174 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002175
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002176 if (maxsplit < 0)
2177 maxsplit = PY_SSIZE_T_MAX;
2178
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002179 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002180 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002181
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002182 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002183 return NULL;
2184 sub = vsub.buf;
2185 n = vsub.len;
2186
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002187 list = stringlib_split(
2188 (PyObject*) self, s, len, sub, n, maxsplit
2189 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002190 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002191 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002192}
2193
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002194/*[clinic input]
2195bytearray.partition
2196
2197 self: self(type="PyByteArrayObject *")
2198 sep: object
2199 /
2200
2201Partition the bytearray into three parts using the given separator.
2202
2203This will search for the separator sep in the bytearray. If the separator is
2204found, returns a 3-tuple containing the part before the separator, the
2205separator itself, and the part after it.
2206
2207If the separator is not found, returns a 3-tuple containing the original
2208bytearray object and two empty bytearray objects.
2209[clinic start generated code]*/
2210
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002211static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002212bytearray_partition(PyByteArrayObject *self, PyObject *sep)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002213/*[clinic end generated code: output=45d2525ddd35f957 input=7d7fe37b1696d506]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002214{
2215 PyObject *bytesep, *result;
2216
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002217 bytesep = PyByteArray_FromObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002218 if (! bytesep)
2219 return NULL;
2220
2221 result = stringlib_partition(
2222 (PyObject*) self,
2223 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2224 bytesep,
2225 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2226 );
2227
2228 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002229 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002230}
2231
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002232/*[clinic input]
2233bytearray.rpartition
2234
2235 self: self(type="PyByteArrayObject *")
2236 sep: object
2237 /
2238
2239Partition the bytes into three parts using the given separator.
2240
2241This will search for the separator sep in the bytearray, starting and the end.
2242If the separator is found, returns a 3-tuple containing the part before the
2243separator, the separator itself, and the part after it.
2244
2245If the separator is not found, returns a 3-tuple containing two empty bytearray
2246objects and the original bytearray object.
2247[clinic start generated code]*/
2248
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002249static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002250bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002251/*[clinic end generated code: output=440de3c9426115e8 input=9b8cd540c1b75853]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002252{
2253 PyObject *bytesep, *result;
2254
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002255 bytesep = PyByteArray_FromObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002256 if (! bytesep)
2257 return NULL;
2258
2259 result = stringlib_rpartition(
2260 (PyObject*) self,
2261 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2262 bytesep,
2263 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2264 );
2265
2266 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002267 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002268}
2269
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002270/*[clinic input]
2271bytearray.rsplit = bytearray.split
2272
2273Return a list of the sections in the bytearray, using sep as the delimiter.
2274
2275Splitting is done starting at the end of the bytearray and working to the front.
2276[clinic start generated code]*/
2277
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002278static PyObject *
2279bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002280/*[clinic end generated code: output=4d648cf3ac65c9e9 input=a68286e4dd692ffe]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002281{
2282 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002283 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002284 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002285 Py_buffer vsub;
2286
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002287 if (maxsplit < 0)
2288 maxsplit = PY_SSIZE_T_MAX;
2289
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002290 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002291 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002292
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002293 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002294 return NULL;
2295 sub = vsub.buf;
2296 n = vsub.len;
2297
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002298 list = stringlib_rsplit(
2299 (PyObject*) self, s, len, sub, n, maxsplit
2300 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002301 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002302 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002303}
2304
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002305/*[clinic input]
2306bytearray.reverse
2307
2308 self: self(type="PyByteArrayObject *")
2309
2310Reverse the order of the values in B in place.
2311[clinic start generated code]*/
2312
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002313static PyObject *
2314bytearray_reverse_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002315/*[clinic end generated code: output=9f7616f29ab309d3 input=7933a499b8597bd1]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002316{
2317 char swap, *head, *tail;
2318 Py_ssize_t i, j, n = Py_SIZE(self);
2319
2320 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002321 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002322 tail = head + n - 1;
2323 for (i = 0; i < j; i++) {
2324 swap = *head;
2325 *head++ = *tail;
2326 *tail-- = swap;
2327 }
2328
2329 Py_RETURN_NONE;
2330}
2331
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002332
2333/*[python input]
2334class bytesvalue_converter(CConverter):
2335 type = 'int'
2336 converter = '_getbytevalue'
2337[python start generated code]*/
2338/*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
2339
2340
2341/*[clinic input]
2342bytearray.insert
2343
2344 self: self(type="PyByteArrayObject *")
2345 index: Py_ssize_t
2346 The index where the value is to be inserted.
2347 item: bytesvalue
2348 The item to be inserted.
2349 /
2350
2351Insert a single item into the bytearray before the given index.
2352[clinic start generated code]*/
2353
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002354static PyObject *
2355bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002356/*[clinic end generated code: output=76c775a70e7b07b7 input=833766836ba30e1e]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002357{
2358 Py_ssize_t n = Py_SIZE(self);
2359 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002360
2361 if (n == PY_SSIZE_T_MAX) {
2362 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002363 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002364 return NULL;
2365 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002366 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2367 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002368 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002369
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002370 if (index < 0) {
2371 index += n;
2372 if (index < 0)
2373 index = 0;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002374 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002375 if (index > n)
2376 index = n;
2377 memmove(buf + index + 1, buf + index, n - index);
2378 buf[index] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002379
2380 Py_RETURN_NONE;
2381}
2382
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002383/*[clinic input]
2384bytearray.append
2385
2386 self: self(type="PyByteArrayObject *")
2387 item: bytesvalue
2388 The item to be appended.
2389 /
2390
2391Append a single item to the end of the bytearray.
2392[clinic start generated code]*/
2393
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002394static PyObject *
2395bytearray_append_impl(PyByteArrayObject *self, int item)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002396/*[clinic end generated code: output=a154e19ed1886cb6 input=ae56ea87380407cc]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002397{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002398 Py_ssize_t n = Py_SIZE(self);
2399
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002400 if (n == PY_SSIZE_T_MAX) {
2401 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002402 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002403 return NULL;
2404 }
2405 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2406 return NULL;
2407
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002408 PyByteArray_AS_STRING(self)[n] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002409
2410 Py_RETURN_NONE;
2411}
2412
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002413/*[clinic input]
2414bytearray.extend
2415
2416 self: self(type="PyByteArrayObject *")
2417 iterable_of_ints: object
2418 The iterable of items to append.
2419 /
2420
2421Append all the items from the iterator or sequence to the end of the bytearray.
2422[clinic start generated code]*/
2423
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002424static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002425bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002426/*[clinic end generated code: output=98155dbe249170b1 input=ce83a5d75b70d850]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002427{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002428 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002429 Py_ssize_t buf_size = 0, len = 0;
2430 int value;
2431 char *buf;
2432
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002433 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002434 if (PyObject_CheckBuffer(iterable_of_ints)) {
2435 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002436 return NULL;
2437
2438 Py_RETURN_NONE;
2439 }
2440
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002441 it = PyObject_GetIter(iterable_of_ints);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002442 if (it == NULL)
2443 return NULL;
2444
Ezio Melotti42da6632011-03-15 05:18:48 +02002445 /* Try to determine the length of the argument. 32 is arbitrary. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002446 buf_size = PyObject_LengthHint(iterable_of_ints, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002447 if (buf_size == -1) {
2448 Py_DECREF(it);
2449 return NULL;
2450 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002451
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002452 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002453 if (bytearray_obj == NULL) {
2454 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002455 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002456 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002457 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002458
2459 while ((item = PyIter_Next(it)) != NULL) {
2460 if (! _getbytevalue(item, &value)) {
2461 Py_DECREF(item);
2462 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002463 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002464 return NULL;
2465 }
2466 buf[len++] = value;
2467 Py_DECREF(item);
2468
2469 if (len >= buf_size) {
2470 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002471 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002472 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002473 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002474 return NULL;
2475 }
2476 /* Recompute the `buf' pointer, since the resizing operation may
2477 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002478 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002479 }
2480 }
2481 Py_DECREF(it);
2482
2483 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002484 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2485 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002486 return NULL;
2487 }
2488
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002489 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2490 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002491 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002492 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002493 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002494
2495 Py_RETURN_NONE;
2496}
2497
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002498/*[clinic input]
2499bytearray.pop
2500
2501 self: self(type="PyByteArrayObject *")
2502 index: Py_ssize_t = -1
2503 The index from where to remove the item.
2504 -1 (the default value) means remove the last item.
2505 /
2506
2507Remove and return a single item from B.
2508
2509If no index argument is given, will pop the last item.
2510[clinic start generated code]*/
2511
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002512static PyObject *
2513bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002514/*[clinic end generated code: output=e0ccd401f8021da8 input=0797e6c0ca9d5a85]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002515{
2516 int value;
2517 Py_ssize_t n = Py_SIZE(self);
2518 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002519
2520 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002521 PyErr_SetString(PyExc_IndexError,
2522 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002523 return NULL;
2524 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002525 if (index < 0)
2526 index += Py_SIZE(self);
2527 if (index < 0 || index >= Py_SIZE(self)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002528 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2529 return NULL;
2530 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002531 if (!_canresize(self))
2532 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002533
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002534 buf = PyByteArray_AS_STRING(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002535 value = buf[index];
2536 memmove(buf + index, buf + index + 1, n - index);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002537 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2538 return NULL;
2539
Mark Dickinson54a3db92009-09-06 10:19:23 +00002540 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002541}
2542
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002543/*[clinic input]
2544bytearray.remove
2545
2546 self: self(type="PyByteArrayObject *")
2547 value: bytesvalue
2548 The value to remove.
2549 /
2550
2551Remove the first occurrence of a value in the bytearray.
2552[clinic start generated code]*/
2553
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002554static PyObject *
2555bytearray_remove_impl(PyByteArrayObject *self, int value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002556/*[clinic end generated code: output=d659e37866709c13 input=47560b11fd856c24]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002557{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002558 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002559 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002560
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002561 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002562 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002563 break;
2564 }
2565 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002566 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002567 return NULL;
2568 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002569 if (!_canresize(self))
2570 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002571
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002572 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002573 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2574 return NULL;
2575
2576 Py_RETURN_NONE;
2577}
2578
2579/* XXX These two helpers could be optimized if argsize == 1 */
2580
2581static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002582lstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002583 void *argptr, Py_ssize_t argsize)
2584{
2585 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002586 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002587 i++;
2588 return i;
2589}
2590
2591static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002592rstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002593 void *argptr, Py_ssize_t argsize)
2594{
2595 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002596 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002597 i--;
2598 return i + 1;
2599}
2600
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002601/*[clinic input]
2602bytearray.strip
2603
2604 bytes: object = None
2605 /
2606
2607Strip leading and trailing bytes contained in the argument.
2608
2609If the argument is omitted or None, strip leading and trailing ASCII whitespace.
2610[clinic start generated code]*/
2611
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002612static PyObject *
2613bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002614/*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002615{
2616 Py_ssize_t left, right, mysize, byteslen;
2617 char *myptr, *bytesptr;
2618 Py_buffer vbytes;
2619
2620 if (bytes == Py_None) {
2621 bytesptr = "\t\n\r\f\v ";
2622 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002623 }
2624 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002625 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002626 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002627 bytesptr = (char *) vbytes.buf;
2628 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002629 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002630 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002631 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002632 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002633 if (left == mysize)
2634 right = left;
2635 else
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002636 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
2637 if (bytes != Py_None)
2638 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002639 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002640}
2641
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002642/*[clinic input]
2643bytearray.lstrip
2644
2645 bytes: object = None
2646 /
2647
2648Strip leading bytes contained in the argument.
2649
2650If the argument is omitted or None, strip leading ASCII whitespace.
2651[clinic start generated code]*/
2652
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002653static PyObject *
2654bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002655/*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002656{
2657 Py_ssize_t left, right, mysize, byteslen;
2658 char *myptr, *bytesptr;
2659 Py_buffer vbytes;
2660
2661 if (bytes == Py_None) {
2662 bytesptr = "\t\n\r\f\v ";
2663 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002664 }
2665 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002666 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002667 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002668 bytesptr = (char *) vbytes.buf;
2669 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002670 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002671 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002672 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002673 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002674 right = mysize;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002675 if (bytes != Py_None)
2676 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002677 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002678}
2679
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002680/*[clinic input]
2681bytearray.rstrip
2682
2683 bytes: object = None
2684 /
2685
2686Strip trailing bytes contained in the argument.
2687
2688If the argument is omitted or None, strip trailing ASCII whitespace.
2689[clinic start generated code]*/
2690
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002691static PyObject *
2692bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002693/*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002694{
2695 Py_ssize_t right, mysize, byteslen;
2696 char *myptr, *bytesptr;
2697 Py_buffer vbytes;
2698
2699 if (bytes == Py_None) {
2700 bytesptr = "\t\n\r\f\v ";
2701 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002702 }
2703 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02002704 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002705 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002706 bytesptr = (char *) vbytes.buf;
2707 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002708 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002709 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002710 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002711 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
2712 if (bytes != Py_None)
2713 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002714 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002715}
2716
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002717/*[clinic input]
2718bytearray.decode
2719
2720 encoding: str(c_default="NULL") = 'utf-8'
2721 The encoding with which to decode the bytearray.
2722 errors: str(c_default="NULL") = 'strict'
2723 The error handling scheme to use for the handling of decoding errors.
2724 The default is 'strict' meaning that decoding errors raise a
2725 UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
2726 as well as any other name registered with codecs.register_error that
2727 can handle UnicodeDecodeErrors.
2728
2729Decode the bytearray using the codec registered for encoding.
2730[clinic start generated code]*/
2731
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002732static PyObject *
2733bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, const char *errors)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002734/*[clinic end generated code: output=7e64e2cc91573b26 input=f28d8f903020257b]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002735{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002736 if (encoding == NULL)
2737 encoding = PyUnicode_GetDefaultEncoding();
Martin v. Löwis0efea322014-07-27 17:29:17 +02002738 return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002739}
2740
2741PyDoc_STRVAR(alloc_doc,
2742"B.__alloc__() -> int\n\
2743\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002744Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002745
2746static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002747bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002748{
2749 return PyLong_FromSsize_t(self->ob_alloc);
2750}
2751
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002752/*[clinic input]
2753bytearray.join
2754
2755 iterable_of_bytes: object
2756 /
2757
2758Concatenate any number of bytes/bytearray objects.
2759
2760The bytearray whose method is called is inserted in between each pair.
2761
2762The result is returned as a new bytearray object.
2763[clinic start generated code]*/
2764
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002765static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002766bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002767/*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002768{
Martin v. Löwis0efea322014-07-27 17:29:17 +02002769 return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002770}
2771
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002772/*[clinic input]
2773bytearray.splitlines
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002774
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002775 keepends: int(py_default="False") = 0
2776
2777Return a list of the lines in the bytearray, breaking at line boundaries.
2778
2779Line breaks are not included in the resulting list unless keepends is given and
2780true.
2781[clinic start generated code]*/
2782
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002783static PyObject *
2784bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002785/*[clinic end generated code: output=4223c94b895f6ad9 input=36f0b25bc792f6c0]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002786{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002787 return stringlib_splitlines(
2788 (PyObject*) self, PyByteArray_AS_STRING(self),
2789 PyByteArray_GET_SIZE(self), keepends
2790 );
2791}
2792
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002793static int
Victor Stinner6430fd52011-09-29 04:02:13 +02002794hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002795{
2796 if (c >= 128)
2797 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00002798 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002799 return c - '0';
2800 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00002801 if (Py_ISUPPER(c))
2802 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002803 if (c >= 'a' && c <= 'f')
2804 return c - 'a' + 10;
2805 }
2806 return -1;
2807}
2808
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002809/*[clinic input]
2810@classmethod
2811bytearray.fromhex
2812
2813 cls: self(type="PyObject*")
2814 string: unicode
2815 /
2816
2817Create a bytearray object from a string of hexadecimal numbers.
2818
2819Spaces between two numbers are accepted.
2820Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
2821[clinic start generated code]*/
2822
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002823static PyObject *
2824bytearray_fromhex_impl(PyObject*cls, PyObject *string)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002825/*[clinic end generated code: output=df3da60129b3700c input=907bbd2d34d9367a]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002826{
2827 PyObject *newbytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002828 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002829 Py_ssize_t hexlen, byteslen, i, j;
2830 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002831 void *data;
2832 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002833
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002834 assert(PyUnicode_Check(string));
2835 if (PyUnicode_READY(string))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002836 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002837 kind = PyUnicode_KIND(string);
2838 data = PyUnicode_DATA(string);
2839 hexlen = PyUnicode_GET_LENGTH(string);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002840
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002841 byteslen = hexlen/2; /* This overestimates if there are spaces */
2842 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2843 if (!newbytes)
2844 return NULL;
2845 buf = PyByteArray_AS_STRING(newbytes);
2846 for (i = j = 0; i < hexlen; i += 2) {
2847 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002848 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002849 i++;
2850 if (i >= hexlen)
2851 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002852 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2853 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002854 if (top == -1 || bot == -1) {
2855 PyErr_Format(PyExc_ValueError,
2856 "non-hexadecimal number found in "
2857 "fromhex() arg at position %zd", i);
2858 goto error;
2859 }
2860 buf[j++] = (top << 4) + bot;
2861 }
2862 if (PyByteArray_Resize(newbytes, j) < 0)
2863 goto error;
2864 return newbytes;
2865
2866 error:
2867 Py_DECREF(newbytes);
2868 return NULL;
2869}
2870
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002871
2872static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002873_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002874{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002875 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002876 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002877 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002878
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002879 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002880 if (dict == NULL) {
2881 PyErr_Clear();
2882 dict = Py_None;
2883 Py_INCREF(dict);
2884 }
2885
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002886 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002887 if (proto < 3) {
2888 /* use str based reduction for backwards compatibility with Python 2.x */
2889 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002890 if (Py_SIZE(self))
2891 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002892 else
2893 latin1 = PyUnicode_FromString("");
2894 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2895 }
2896 else {
2897 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002898 if (Py_SIZE(self)) {
2899 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002900 }
2901 else {
2902 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2903 }
2904 }
2905}
2906
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002907/*[clinic input]
2908bytearray.__reduce__ as bytearray_reduce
2909
2910 self: self(type="PyByteArrayObject *")
2911
2912Return state information for pickling.
2913[clinic start generated code]*/
2914
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002915static PyObject *
2916bytearray_reduce_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002917/*[clinic end generated code: output=52bf304086464cab input=fbb07de4d102a03a]*/
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002918{
2919 return _common_reduce(self, 2);
2920}
2921
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002922/*[clinic input]
2923bytearray.__reduce_ex__ as bytearray_reduce_ex
2924
2925 self: self(type="PyByteArrayObject *")
2926 proto: int = 0
2927 /
2928
2929Return state information for pickling.
2930[clinic start generated code]*/
2931
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002932static PyObject *
2933bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002934/*[clinic end generated code: output=52eac33377197520 input=0e091a42ca6dbd91]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002935{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002936 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002937}
2938
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002939/*[clinic input]
2940bytearray.__sizeof__ as bytearray_sizeof
2941
2942 self: self(type="PyByteArrayObject *")
2943
2944Returns the size of the bytearray object in memory, in bytes.
2945[clinic start generated code]*/
2946
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002947static PyObject *
2948bytearray_sizeof_impl(PyByteArrayObject *self)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002949/*[clinic end generated code: output=738abdd17951c427 input=6b23d305362b462b]*/
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002950{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002951 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002952
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002953 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2954 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002955}
2956
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002957static PySequenceMethods bytearray_as_sequence = {
2958 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002959 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002960 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2961 (ssizeargfunc)bytearray_getitem, /* sq_item */
2962 0, /* sq_slice */
2963 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2964 0, /* sq_ass_slice */
2965 (objobjproc)bytearray_contains, /* sq_contains */
2966 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2967 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002968};
2969
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002970static PyMappingMethods bytearray_as_mapping = {
2971 (lenfunc)bytearray_length,
2972 (binaryfunc)bytearray_subscript,
2973 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002974};
2975
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002976static PyBufferProcs bytearray_as_buffer = {
2977 (getbufferproc)bytearray_getbuffer,
2978 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002979};
2980
2981static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002982bytearray_methods[] = {
2983 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002984 BYTEARRAY_REDUCE_METHODDEF
2985 BYTEARRAY_REDUCE_EX_METHODDEF
2986 BYTEARRAY_SIZEOF_METHODDEF
2987 BYTEARRAY_APPEND_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002988 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2989 _Py_capitalize__doc__},
2990 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002991 BYTEARRAY_CLEAR_METHODDEF
2992 BYTEARRAY_COPY_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002993 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002994 BYTEARRAY_DECODE_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002995 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Ezio Melotti745d54d2013-11-16 19:10:57 +02002996 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002997 expandtabs__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002998 BYTEARRAY_EXTEND_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002999 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003000 BYTEARRAY_FROMHEX_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003001 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003002 BYTEARRAY_INSERT_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003003 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
3004 _Py_isalnum__doc__},
3005 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
3006 _Py_isalpha__doc__},
3007 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
3008 _Py_isdigit__doc__},
3009 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
3010 _Py_islower__doc__},
3011 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
3012 _Py_isspace__doc__},
3013 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
3014 _Py_istitle__doc__},
3015 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
3016 _Py_isupper__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003017 BYTEARRAY_JOIN_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003018 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
3019 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003020 BYTEARRAY_LSTRIP_METHODDEF
3021 BYTEARRAY_MAKETRANS_METHODDEF
3022 BYTEARRAY_PARTITION_METHODDEF
3023 BYTEARRAY_POP_METHODDEF
3024 BYTEARRAY_REMOVE_METHODDEF
3025 BYTEARRAY_REPLACE_METHODDEF
3026 BYTEARRAY_REVERSE_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003027 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
3028 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003029 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003030 BYTEARRAY_RPARTITION_METHODDEF
3031 BYTEARRAY_RSPLIT_METHODDEF
3032 BYTEARRAY_RSTRIP_METHODDEF
3033 BYTEARRAY_SPLIT_METHODDEF
3034 BYTEARRAY_SPLITLINES_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003035 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003036 startswith__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003037 BYTEARRAY_STRIP_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003038 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
3039 _Py_swapcase__doc__},
3040 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003041 BYTEARRAY_TRANSLATE_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003042 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
3043 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
3044 {NULL}
3045};
3046
Ethan Furmanb95b5612015-01-23 20:05:18 -08003047static PyObject *
3048bytearray_mod(PyObject *v, PyObject *w)
3049{
3050 if (!PyByteArray_Check(v))
3051 Py_RETURN_NOTIMPLEMENTED;
3052 return bytearray_format((PyByteArrayObject *)v, w);
3053}
3054
3055static PyNumberMethods bytearray_as_number = {
3056 0, /*nb_add*/
3057 0, /*nb_subtract*/
3058 0, /*nb_multiply*/
3059 bytearray_mod, /*nb_remainder*/
3060};
3061
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003062PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00003063"bytearray(iterable_of_ints) -> bytearray\n\
3064bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003065bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
3066bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
3067bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003068\n\
3069Construct an mutable bytearray object from:\n\
3070 - an iterable yielding integers in range(256)\n\
3071 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003072 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003073 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003074 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003075
3076
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003077static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003078
3079PyTypeObject PyByteArray_Type = {
3080 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3081 "bytearray",
3082 sizeof(PyByteArrayObject),
3083 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003084 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003085 0, /* tp_print */
3086 0, /* tp_getattr */
3087 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003088 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003089 (reprfunc)bytearray_repr, /* tp_repr */
Ethan Furmanb95b5612015-01-23 20:05:18 -08003090 &bytearray_as_number, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003091 &bytearray_as_sequence, /* tp_as_sequence */
3092 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003093 0, /* tp_hash */
3094 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003095 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003096 PyObject_GenericGetAttr, /* tp_getattro */
3097 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003098 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003099 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003100 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003101 0, /* tp_traverse */
3102 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003103 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003104 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003105 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003106 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003107 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003108 0, /* tp_members */
3109 0, /* tp_getset */
3110 0, /* tp_base */
3111 0, /* tp_dict */
3112 0, /* tp_descr_get */
3113 0, /* tp_descr_set */
3114 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003115 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003116 PyType_GenericAlloc, /* tp_alloc */
3117 PyType_GenericNew, /* tp_new */
3118 PyObject_Del, /* tp_free */
3119};
3120
3121/*********************** Bytes Iterator ****************************/
3122
3123typedef struct {
3124 PyObject_HEAD
3125 Py_ssize_t it_index;
3126 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
3127} bytesiterobject;
3128
3129static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003130bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003131{
3132 _PyObject_GC_UNTRACK(it);
3133 Py_XDECREF(it->it_seq);
3134 PyObject_GC_Del(it);
3135}
3136
3137static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003138bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003139{
3140 Py_VISIT(it->it_seq);
3141 return 0;
3142}
3143
3144static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003145bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003146{
3147 PyByteArrayObject *seq;
3148 PyObject *item;
3149
3150 assert(it != NULL);
3151 seq = it->it_seq;
3152 if (seq == NULL)
3153 return NULL;
3154 assert(PyByteArray_Check(seq));
3155
3156 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
3157 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003158 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003159 if (item != NULL)
3160 ++it->it_index;
3161 return item;
3162 }
3163
3164 Py_DECREF(seq);
3165 it->it_seq = NULL;
3166 return NULL;
3167}
3168
3169static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003170bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003171{
3172 Py_ssize_t len = 0;
3173 if (it->it_seq)
3174 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3175 return PyLong_FromSsize_t(len);
3176}
3177
3178PyDoc_STRVAR(length_hint_doc,
3179 "Private method returning an estimate of len(list(it)).");
3180
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003181static PyObject *
3182bytearrayiter_reduce(bytesiterobject *it)
3183{
3184 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02003185 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003186 it->it_seq, it->it_index);
3187 } else {
3188 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
3189 if (u == NULL)
3190 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02003191 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003192 }
3193}
3194
3195static PyObject *
3196bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3197{
3198 Py_ssize_t index = PyLong_AsSsize_t(state);
3199 if (index == -1 && PyErr_Occurred())
3200 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +00003201 if (it->it_seq != NULL) {
3202 if (index < 0)
3203 index = 0;
3204 else if (index > PyByteArray_GET_SIZE(it->it_seq))
3205 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
3206 it->it_index = index;
3207 }
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003208 Py_RETURN_NONE;
3209}
3210
3211PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3212
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003213static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003214 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003215 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003216 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003217 bytearray_reduce__doc__},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003218 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3219 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003220 {NULL, NULL} /* sentinel */
3221};
3222
3223PyTypeObject PyByteArrayIter_Type = {
3224 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3225 "bytearray_iterator", /* tp_name */
3226 sizeof(bytesiterobject), /* tp_basicsize */
3227 0, /* tp_itemsize */
3228 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003229 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003230 0, /* tp_print */
3231 0, /* tp_getattr */
3232 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003233 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003234 0, /* tp_repr */
3235 0, /* tp_as_number */
3236 0, /* tp_as_sequence */
3237 0, /* tp_as_mapping */
3238 0, /* tp_hash */
3239 0, /* tp_call */
3240 0, /* tp_str */
3241 PyObject_GenericGetAttr, /* tp_getattro */
3242 0, /* tp_setattro */
3243 0, /* tp_as_buffer */
3244 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3245 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003246 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003247 0, /* tp_clear */
3248 0, /* tp_richcompare */
3249 0, /* tp_weaklistoffset */
3250 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003251 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3252 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003253 0,
3254};
3255
3256static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003257bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003258{
3259 bytesiterobject *it;
3260
3261 if (!PyByteArray_Check(seq)) {
3262 PyErr_BadInternalCall();
3263 return NULL;
3264 }
3265 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3266 if (it == NULL)
3267 return NULL;
3268 it->it_index = 0;
3269 Py_INCREF(seq);
3270 it->it_seq = (PyByteArrayObject *)seq;
3271 _PyObject_GC_TRACK(it);
3272 return (PyObject *)it;
3273}