Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(22)

Delta Between Two Patch Sets: Objects/bytearrayobject.c

Issue 24467: bytearray pop and remove Buffer Over-read
Left Patch Set: Created 4 years, 7 months ago
Right Patch Set: Created 4 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_bytes.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* PyBytes (bytearray) implementation */ 1 /* PyByteArray (bytearray) implementation */
2 2
3 #define PY_SSIZE_T_CLEAN 3 #define PY_SSIZE_T_CLEAN
4 #include "Python.h" 4 #include "Python.h"
5 #include "structmember.h" 5 #include "structmember.h"
6 #include "bytes_methods.h" 6 #include "bytes_methods.h"
7 #include "bytesobject.h"
8 #include "pystrhex.h"
9
10 /*[clinic input]
11 class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
12 [clinic start generated code]*/
13 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/
7 14
8 char _PyByteArray_empty_string[] = ""; 15 char _PyByteArray_empty_string[] = "";
9 16
10 void 17 void
11 PyByteArray_Fini(void) 18 PyByteArray_Fini(void)
12 { 19 {
13 } 20 }
14 21
15 int 22 int
16 PyByteArray_Init(void) 23 PyByteArray_Init(void)
17 { 24 {
18 return 1; 25 return 1;
19 } 26 }
20 27
21 /* end nullbytes support */ 28 /* end nullbytes support */
22 29
23 /* Helpers */ 30 /* Helpers */
24 31
25 static int 32 static int
26 _getbytevalue(PyObject* arg, int *value) 33 _getbytevalue(PyObject* arg, int *value)
27 { 34 {
28 long face_value; 35 long face_value;
29 36
30 if (PyBytes_CheckExact(arg)) { 37 if (PyLong_Check(arg)) {
31 if (Py_SIZE(arg) != 1) {
32 PyErr_SetString(PyExc_ValueError, "string must be of size 1");
33 return 0;
34 }
35 *value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
36 return 1;
37 }
38 else if (PyInt_Check(arg) || PyLong_Check(arg)) {
39 face_value = PyLong_AsLong(arg); 38 face_value = PyLong_AsLong(arg);
40 } 39 } else {
41 else {
42 PyObject *index = PyNumber_Index(arg); 40 PyObject *index = PyNumber_Index(arg);
43 if (index == NULL) { 41 if (index == NULL) {
44 PyErr_Format(PyExc_TypeError, 42 PyErr_Format(PyExc_TypeError, "an integer is required");
45 "an integer or string of size 1 is required"); 43 *value = -1;
46 return 0; 44 return 0;
47 } 45 }
48 face_value = PyLong_AsLong(index); 46 face_value = PyLong_AsLong(index);
49 Py_DECREF(index); 47 Py_DECREF(index);
50 } 48 }
51 49
52 if (face_value < 0 || face_value >= 256) { 50 if (face_value < 0 || face_value >= 256) {
53 /* this includes the OverflowError in case the long is too large */ 51 /* this includes the OverflowError in case the long is too large */
54 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); 52 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
53 *value = -1;
55 return 0; 54 return 0;
56 } 55 }
57 56
58 *value = face_value; 57 *value = face_value;
59 return 1; 58 return 1;
60 } 59 }
61 60
62 static Py_ssize_t
63 bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const voi d **ptr)
64 {
65 if ( index != 0 ) {
66 PyErr_SetString(PyExc_SystemError,
67 "accessing non-existent bytes segment");
68 return -1;
69 }
70 *ptr = (void *)PyByteArray_AS_STRING(self);
71 return Py_SIZE(self);
72 }
73
74 static Py_ssize_t
75 bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const vo id **ptr)
76 {
77 if ( index != 0 ) {
78 PyErr_SetString(PyExc_SystemError,
79 "accessing non-existent bytes segment");
80 return -1;
81 }
82 *ptr = (void *)PyByteArray_AS_STRING(self);
83 return Py_SIZE(self);
84 }
85
86 static Py_ssize_t
87 bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
88 {
89 if ( lenp )
90 *lenp = Py_SIZE(self);
91 return 1;
92 }
93
94 static Py_ssize_t
95 bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const cha r **ptr)
96 {
97 if ( index != 0 ) {
98 PyErr_SetString(PyExc_SystemError,
99 "accessing non-existent bytes segment");
100 return -1;
101 }
102 *ptr = PyByteArray_AS_STRING(self);
103 return Py_SIZE(self);
104 }
105
106 static int 61 static int
107 bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) 62 bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
108 { 63 {
109 int ret;
110 void *ptr; 64 void *ptr;
111 if (view == NULL) { 65 if (view == NULL) {
112 obj->ob_exports++; 66 PyErr_SetString(PyExc_BufferError,
113 return 0; 67 "bytearray_getbuffer: view==NULL argument is obsolete");
68 return -1;
114 } 69 }
115 ptr = (void *) PyByteArray_AS_STRING(obj); 70 ptr = (void *) PyByteArray_AS_STRING(obj);
116 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); 71 /* cannot fail if view != NULL and readonly == 0 */
117 if (ret >= 0) { 72 (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
118 obj->ob_exports++; 73 obj->ob_exports++;
119 } 74 return 0;
120 return ret;
121 } 75 }
122 76
123 static void 77 static void
124 bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) 78 bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
125 { 79 {
126 obj->ob_exports--; 80 obj->ob_exports--;
127 }
128
129 static Py_ssize_t
130 _getbuffer(PyObject *obj, Py_buffer *view)
131 {
132 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
133
134 if (buffer == NULL || buffer->bf_getbuffer == NULL)
135 {
136 PyErr_Format(PyExc_TypeError,
137 "Type %.100s doesn't support the buffer API",
138 Py_TYPE(obj)->tp_name);
139 return -1;
140 }
141
142 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
143 return -1;
144 return view->len;
145 } 81 }
146 82
147 static int 83 static int
148 _canresize(PyByteArrayObject *self) 84 _canresize(PyByteArrayObject *self)
149 { 85 {
150 if (self->ob_exports > 0) { 86 if (self->ob_exports > 0) {
151 PyErr_SetString(PyExc_BufferError, 87 PyErr_SetString(PyExc_BufferError,
152 "Existing exports of data: object cannot be re-sized"); 88 "Existing exports of data: object cannot be re-sized");
153 return 0; 89 return 0;
154 } 90 }
155 return 1; 91 return 1;
156 } 92 }
157 93
94 #include "clinic/bytearrayobject.c.h"
95
158 /* Direct API functions */ 96 /* Direct API functions */
159 97
160 PyObject * 98 PyObject *
161 PyByteArray_FromObject(PyObject *input) 99 PyByteArray_FromObject(PyObject *input)
162 { 100 {
163 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type, 101 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
164 input, NULL); 102 input, NULL);
165 } 103 }
166 104
167 PyObject * 105 PyObject *
168 PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size) 106 PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
169 { 107 {
170 PyByteArrayObject *new; 108 PyByteArrayObject *new;
171 Py_ssize_t alloc; 109 Py_ssize_t alloc;
172 110
173 if (size < 0) { 111 if (size < 0) {
174 PyErr_SetString(PyExc_SystemError, 112 PyErr_SetString(PyExc_SystemError,
175 "Negative size passed to PyByteArray_FromStringAndSize"); 113 "Negative size passed to PyByteArray_FromStringAndSize");
176 return NULL; 114 return NULL;
177 } 115 }
178 116
117 /* Prevent buffer overflow when setting alloc to size+1. */
118 if (size == PY_SSIZE_T_MAX) {
119 return PyErr_NoMemory();
120 }
121
179 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type); 122 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
180 if (new == NULL) 123 if (new == NULL)
181 return NULL; 124 return NULL;
182 125
183 if (size == 0) { 126 if (size == 0) {
184 new->ob_bytes = NULL; 127 new->ob_bytes = NULL;
185 alloc = 0; 128 alloc = 0;
186 } 129 }
187 else { 130 else {
188 alloc = size + 1; 131 alloc = size + 1;
189 new->ob_bytes = PyMem_Malloc(alloc); 132 new->ob_bytes = PyObject_Malloc(alloc);
190 if (new->ob_bytes == NULL) { 133 if (new->ob_bytes == NULL) {
191 Py_DECREF(new); 134 Py_DECREF(new);
192 return PyErr_NoMemory(); 135 return PyErr_NoMemory();
193 } 136 }
194 if (bytes != NULL && size > 0) 137 if (bytes != NULL && size > 0)
195 memcpy(new->ob_bytes, bytes, size); 138 memcpy(new->ob_bytes, bytes, size);
196 new->ob_bytes[size] = '\0'; /* Trailing null byte */ 139 new->ob_bytes[size] = '\0'; /* Trailing null byte */
197 } 140 }
198 Py_SIZE(new) = size; 141 Py_SIZE(new) = size;
199 new->ob_alloc = alloc; 142 new->ob_alloc = alloc;
143 new->ob_start = new->ob_bytes;
200 new->ob_exports = 0; 144 new->ob_exports = 0;
201 145
202 return (PyObject *)new; 146 return (PyObject *)new;
203 } 147 }
204 148
205 Py_ssize_t 149 Py_ssize_t
206 PyByteArray_Size(PyObject *self) 150 PyByteArray_Size(PyObject *self)
207 { 151 {
208 assert(self != NULL); 152 assert(self != NULL);
209 assert(PyByteArray_Check(self)); 153 assert(PyByteArray_Check(self));
210 154
211 return PyByteArray_GET_SIZE(self); 155 return PyByteArray_GET_SIZE(self);
212 } 156 }
213 157
214 char * 158 char *
215 PyByteArray_AsString(PyObject *self) 159 PyByteArray_AsString(PyObject *self)
216 { 160 {
217 assert(self != NULL); 161 assert(self != NULL);
218 assert(PyByteArray_Check(self)); 162 assert(PyByteArray_Check(self));
219 163
220 return PyByteArray_AS_STRING(self); 164 return PyByteArray_AS_STRING(self);
221 } 165 }
222 166
223 int 167 int
224 PyByteArray_Resize(PyObject *self, Py_ssize_t size) 168 PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
225 { 169 {
226 void *sval; 170 void *sval;
227 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc; 171 PyByteArrayObject *obj = ((PyByteArrayObject *)self);
172 /* All computations are done unsigned to avoid integer overflows
173 (see issue #22335). */
174 size_t alloc = (size_t) obj->ob_alloc;
175 size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
176 size_t size = (size_t) requested_size;
228 177
229 assert(self != NULL); 178 assert(self != NULL);
230 assert(PyByteArray_Check(self)); 179 assert(PyByteArray_Check(self));
231 assert(size >= 0); 180 assert(logical_offset <= alloc);
232 181 assert(requested_size >= 0);
233 if (size == Py_SIZE(self)) { 182
183 if (requested_size == Py_SIZE(self)) {
234 return 0; 184 return 0;
235 } 185 }
236 if (!_canresize((PyByteArrayObject *)self)) { 186 if (!_canresize(obj)) {
237 return -1; 187 return -1;
238 } 188 }
239 189
240 if (size < alloc / 2) { 190 if (size + logical_offset + 1 <= alloc) {
241 /* Major downsize; resize down to exact size */ 191 /* Current buffer is large enough to host the requested size,
242 alloc = size + 1; 192 decide on a strategy. */
243 } 193 if (size < alloc / 2) {
244 else if (size < alloc) { 194 /* Major downsize; resize down to exact size */
245 /* Within allocated size; quick exit */ 195 alloc = size + 1;
246 Py_SIZE(self) = size; 196 }
247 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */ 197 else {
248 return 0; 198 /* Minor downsize; quick exit */
249 } 199 Py_SIZE(self) = size;
250 else if (size <= alloc * 1.125) { 200 PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
251 /* Moderate upsize; overallocate similar to list_resize() */ 201 return 0;
252 alloc = size + (size >> 3) + (size < 9 ? 3 : 6); 202 }
253 } 203 }
254 else { 204 else {
255 /* Major upsize; resize up to exact size */ 205 /* Need growing, decide on a strategy */
256 alloc = size + 1; 206 if (size <= alloc * 1.125) {
257 } 207 /* Moderate upsize; overallocate similar to list_resize() */
258 208 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
259 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc); 209 }
260 if (sval == NULL) { 210 else {
211 /* Major upsize; resize up to exact size */
212 alloc = size + 1;
213 }
214 }
215 if (alloc > PY_SSIZE_T_MAX) {
261 PyErr_NoMemory(); 216 PyErr_NoMemory();
262 return -1; 217 return -1;
263 } 218 }
264 219
265 ((PyByteArrayObject *)self)->ob_bytes = sval; 220 if (logical_offset > 0) {
221 sval = PyObject_Malloc(alloc);
222 if (sval == NULL) {
223 PyErr_NoMemory();
224 return -1;
225 }
226 memcpy(sval, PyByteArray_AS_STRING(self),
227 Py_MIN(requested_size, Py_SIZE(self)));
228 PyObject_Free(obj->ob_bytes);
229 }
230 else {
231 sval = PyObject_Realloc(obj->ob_bytes, alloc);
232 if (sval == NULL) {
233 PyErr_NoMemory();
234 return -1;
235 }
236 }
237
238 obj->ob_bytes = obj->ob_start = sval;
266 Py_SIZE(self) = size; 239 Py_SIZE(self) = size;
267 ((PyByteArrayObject *)self)->ob_alloc = alloc; 240 obj->ob_alloc = alloc;
268 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */ 241 obj->ob_bytes[size] = '\0'; /* Trailing null byte */
269 242
270 return 0; 243 return 0;
271 } 244 }
272 245
273 PyObject * 246 PyObject *
274 PyByteArray_Concat(PyObject *a, PyObject *b) 247 PyByteArray_Concat(PyObject *a, PyObject *b)
275 { 248 {
276 Py_ssize_t size; 249 Py_ssize_t size;
277 Py_buffer va, vb; 250 Py_buffer va, vb;
278 PyByteArrayObject *result = NULL; 251 PyByteArrayObject *result = NULL;
279 252
280 va.len = -1; 253 va.len = -1;
281 vb.len = -1; 254 vb.len = -1;
282 if (_getbuffer(a, &va) < 0 || 255 if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
283 _getbuffer(b, &vb) < 0) { 256 PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
284 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", 257 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
285 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); 258 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
286 goto done; 259 goto done;
287 } 260 }
288 261
289 size = va.len + vb.len; 262 size = va.len + vb.len;
290 if (size < 0) { 263 if (size < 0) {
291 PyErr_NoMemory(); 264 PyErr_NoMemory();
292 goto done; 265 goto done;
293 } 266 }
294 267
295 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size); 268 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
296 if (result != NULL) { 269 if (result != NULL) {
297 memcpy(result->ob_bytes, va.buf, va.len); 270 memcpy(result->ob_bytes, va.buf, va.len);
298 memcpy(result->ob_bytes + va.len, vb.buf, vb.len); 271 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
299 } 272 }
300 273
301 done: 274 done:
302 if (va.len != -1) 275 if (va.len != -1)
303 PyBuffer_Release(&va); 276 PyBuffer_Release(&va);
304 if (vb.len != -1) 277 if (vb.len != -1)
305 PyBuffer_Release(&vb); 278 PyBuffer_Release(&vb);
306 return (PyObject *)result; 279 return (PyObject *)result;
307 } 280 }
308 281
282 static PyObject *
283 bytearray_format(PyByteArrayObject *self, PyObject *args)
284 {
285 PyObject *bytes_in, *bytes_out, *res;
286 char *bytestring;
287
288 if (self == NULL || !PyByteArray_Check(self) || args == NULL) {
289 PyErr_BadInternalCall();
290 return NULL;
291 }
292 bytestring = PyByteArray_AS_STRING(self);
293 bytes_in = PyBytes_FromString(bytestring);
294 if (bytes_in == NULL)
295 return NULL;
296 bytes_out = _PyBytes_Format(bytes_in, args);
297 Py_DECREF(bytes_in);
298 if (bytes_out == NULL)
299 return NULL;
300 res = PyByteArray_FromObject(bytes_out);
301 Py_DECREF(bytes_out);
302 if (res == NULL)
303 return NULL;
304 return res;
305 }
306
309 /* Functions stuffed into the type object */ 307 /* Functions stuffed into the type object */
310 308
311 static Py_ssize_t 309 static Py_ssize_t
312 bytearray_length(PyByteArrayObject *self) 310 bytearray_length(PyByteArrayObject *self)
313 { 311 {
314 return Py_SIZE(self); 312 return Py_SIZE(self);
315 } 313 }
316 314
317 static PyObject * 315 static PyObject *
318 bytearray_iconcat(PyByteArrayObject *self, PyObject *other) 316 bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
319 { 317 {
320 Py_ssize_t mysize; 318 Py_ssize_t mysize;
321 Py_ssize_t size; 319 Py_ssize_t size;
322 Py_buffer vo; 320 Py_buffer vo;
323 321
324 if (_getbuffer(other, &vo) < 0) { 322 if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
325 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", 323 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
326 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name); 324 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
327 return NULL; 325 return NULL;
328 } 326 }
329 327
330 mysize = Py_SIZE(self); 328 mysize = Py_SIZE(self);
331 size = mysize + vo.len; 329 size = mysize + vo.len;
332 if (size < 0) { 330 if (size < 0) {
333 PyBuffer_Release(&vo); 331 PyBuffer_Release(&vo);
334 return PyErr_NoMemory(); 332 return PyErr_NoMemory();
335 } 333 }
336 if (size < self->ob_alloc) { 334 if (PyByteArray_Resize((PyObject *)self, size) < 0) {
337 Py_SIZE(self) = size;
338 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
339 }
340 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
341 PyBuffer_Release(&vo); 335 PyBuffer_Release(&vo);
342 return NULL; 336 return NULL;
343 } 337 }
344 memcpy(self->ob_bytes + mysize, vo.buf, vo.len); 338 memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
345 PyBuffer_Release(&vo); 339 PyBuffer_Release(&vo);
346 Py_INCREF(self); 340 Py_INCREF(self);
347 return (PyObject *)self; 341 return (PyObject *)self;
348 } 342 }
349 343
350 static PyObject * 344 static PyObject *
351 bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) 345 bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
352 { 346 {
353 PyByteArrayObject *result; 347 PyByteArrayObject *result;
354 Py_ssize_t mysize; 348 Py_ssize_t mysize;
355 Py_ssize_t size; 349 Py_ssize_t size;
356 350
357 if (count < 0) 351 if (count < 0)
358 count = 0; 352 count = 0;
359 mysize = Py_SIZE(self); 353 mysize = Py_SIZE(self);
354 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
355 return PyErr_NoMemory();
360 size = mysize * count; 356 size = mysize * count;
361 if (count != 0 && size / count != mysize)
362 return PyErr_NoMemory();
363 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); 357 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
364 if (result != NULL && size != 0) { 358 if (result != NULL && size != 0) {
365 if (mysize == 1) 359 if (mysize == 1)
366 memset(result->ob_bytes, self->ob_bytes[0], size); 360 memset(result->ob_bytes, self->ob_bytes[0], size);
367 else { 361 else {
368 Py_ssize_t i; 362 Py_ssize_t i;
369 for (i = 0; i < count; i++) 363 for (i = 0; i < count; i++)
370 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize); 364 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
371 } 365 }
372 } 366 }
373 return (PyObject *)result; 367 return (PyObject *)result;
374 } 368 }
375 369
376 static PyObject * 370 static PyObject *
377 bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) 371 bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
378 { 372 {
379 Py_ssize_t mysize; 373 Py_ssize_t mysize;
380 Py_ssize_t size; 374 Py_ssize_t size;
375 char *buf;
381 376
382 if (count < 0) 377 if (count < 0)
383 count = 0; 378 count = 0;
384 mysize = Py_SIZE(self); 379 mysize = Py_SIZE(self);
380 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
381 return PyErr_NoMemory();
385 size = mysize * count; 382 size = mysize * count;
386 if (count != 0 && size / count != mysize) 383 if (PyByteArray_Resize((PyObject *)self, size) < 0)
387 return PyErr_NoMemory(); 384 return NULL;
388 if (size < self->ob_alloc) { 385
389 Py_SIZE(self) = size; 386 buf = PyByteArray_AS_STRING(self);
390 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
391 }
392 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
393 return NULL;
394
395 if (mysize == 1) 387 if (mysize == 1)
396 memset(self->ob_bytes, self->ob_bytes[0], size); 388 memset(buf, buf[0], size);
397 else { 389 else {
398 Py_ssize_t i; 390 Py_ssize_t i;
399 for (i = 1; i < count; i++) 391 for (i = 1; i < count; i++)
400 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize); 392 memcpy(buf + i*mysize, buf, mysize);
401 } 393 }
402 394
403 Py_INCREF(self); 395 Py_INCREF(self);
404 return (PyObject *)self; 396 return (PyObject *)self;
405 } 397 }
406 398
407 static PyObject * 399 static PyObject *
408 bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i) 400 bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
409 { 401 {
410 if (i < 0) 402 if (i < 0)
411 i += Py_SIZE(self); 403 i += Py_SIZE(self);
412 if (i < 0 || i >= Py_SIZE(self)) { 404 if (i < 0 || i >= Py_SIZE(self)) {
413 PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); 405 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
414 return NULL; 406 return NULL;
415 } 407 }
416 return PyInt_FromLong((unsigned char)(self->ob_bytes[i])); 408 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
417 } 409 }
418 410
419 static PyObject * 411 static PyObject *
420 bytearray_subscript(PyByteArrayObject *self, PyObject *index) 412 bytearray_subscript(PyByteArrayObject *self, PyObject *index)
421 { 413 {
422 if (PyIndex_Check(index)) { 414 if (PyIndex_Check(index)) {
423 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError); 415 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
424 416
425 if (i == -1 && PyErr_Occurred()) 417 if (i == -1 && PyErr_Occurred())
426 return NULL; 418 return NULL;
427 419
428 if (i < 0) 420 if (i < 0)
429 i += PyByteArray_GET_SIZE(self); 421 i += PyByteArray_GET_SIZE(self);
430 422
431 if (i < 0 || i >= Py_SIZE(self)) { 423 if (i < 0 || i >= Py_SIZE(self)) {
432 PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); 424 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
433 return NULL; 425 return NULL;
434 } 426 }
435 return PyInt_FromLong((unsigned char)(self->ob_bytes[i])); 427 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
436 } 428 }
437 else if (PySlice_Check(index)) { 429 else if (PySlice_Check(index)) {
438 Py_ssize_t start, stop, step, slicelength, cur, i; 430 Py_ssize_t start, stop, step, slicelength, cur, i;
439 if (PySlice_GetIndicesEx((PySliceObject *)index, 431 if (PySlice_GetIndicesEx(index,
440 PyByteArray_GET_SIZE(self), 432 PyByteArray_GET_SIZE(self),
441 &start, &stop, &step, &slicelength) < 0) { 433 &start, &stop, &step, &slicelength) < 0) {
442 return NULL; 434 return NULL;
443 } 435 }
444 436
445 if (slicelength <= 0) 437 if (slicelength <= 0)
446 return PyByteArray_FromStringAndSize("", 0); 438 return PyByteArray_FromStringAndSize("", 0);
447 else if (step == 1) { 439 else if (step == 1) {
448 return PyByteArray_FromStringAndSize(self->ob_bytes + start, 440 return PyByteArray_FromStringAndSize(
449 slicelength); 441 PyByteArray_AS_STRING(self) + start, slicelength);
450 } 442 }
451 else { 443 else {
452 char *source_buf = PyByteArray_AS_STRING(self); 444 char *source_buf = PyByteArray_AS_STRING(self);
453 char *result_buf = (char *)PyMem_Malloc(slicelength); 445 char *result_buf;
454 PyObject *result; 446 PyObject *result;
455 447
456 if (result_buf == NULL) 448 result = PyByteArray_FromStringAndSize(NULL, slicelength);
457 return PyErr_NoMemory(); 449 if (result == NULL)
458 450 return NULL;
451
452 result_buf = PyByteArray_AS_STRING(result);
459 for (cur = start, i = 0; i < slicelength; 453 for (cur = start, i = 0; i < slicelength;
460 cur += step, i++) { 454 cur += step, i++) {
461 result_buf[i] = source_buf[cur]; 455 result_buf[i] = source_buf[cur];
462 } 456 }
463 result = PyByteArray_FromStringAndSize(result_buf, slicelength);
464 PyMem_Free(result_buf);
465 return result; 457 return result;
466 } 458 }
467 } 459 }
468 else { 460 else {
469 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers"); 461 PyErr_Format(PyExc_TypeError,
470 return NULL; 462 "bytearray indices must be integers or slices, not %.200s",
471 } 463 Py_TYPE(index)->tp_name);
464 return NULL;
465 }
466 }
467
468 static int
469 bytearray_setslice_linear(PyByteArrayObject *self,
470 Py_ssize_t lo, Py_ssize_t hi,
471 char *bytes, Py_ssize_t bytes_len)
472 {
473 Py_ssize_t avail = hi - lo;
474 char *buf = PyByteArray_AS_STRING(self);
475 Py_ssize_t growth = bytes_len - avail;
476 int res = 0;
477 assert(avail >= 0);
478
479 if (growth < 0) {
480 if (!_canresize(self))
481 return -1;
482
483 if (lo == 0) {
484 /* Shrink the buffer by advancing its logical start */
485 self->ob_start -= growth;
486 /*
487 0 lo hi old_size
488 | |<----avail----->|<-----tail------>|
489 | |<-bytes_len->|<-----tail------>|
490 0 new_lo new_hi new_size
491 */
492 }
493 else {
494 /*
495 0 lo hi old_size
496 | |<----avail----->|<-----tomove------>|
497 | |<-bytes_len->|<-----tomove------>|
498 0 lo new_hi new_size
499 */
500 memmove(buf + lo + bytes_len, buf + hi,
501 Py_SIZE(self) - hi);
502 }
503 if (PyByteArray_Resize((PyObject *)self,
504 Py_SIZE(self) + growth) < 0) {
505 /* Issue #19578: Handling the memory allocation failure here is
506 tricky here because the bytearray object has already been
507 modified. Depending on growth and lo, the behaviour is
508 different.
509
510 If growth < 0 and lo != 0, the operation is completed, but a
511 MemoryError is still raised and the memory block is not
512 shrinked. Otherwise, the bytearray is restored in its previous
513 state and a MemoryError is raised. */
514 if (lo == 0) {
515 self->ob_start += growth;
516 return -1;
517 }
518 /* memmove() removed bytes, the bytearray object cannot be
519 restored in its previous state. */
520 Py_SIZE(self) += growth;
521 res = -1;
522 }
523 buf = PyByteArray_AS_STRING(self);
524 }
525 else if (growth > 0) {
526 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
527 PyErr_NoMemory();
528 return -1;
529 }
530
531 if (PyByteArray_Resize((PyObject *)self,
532 Py_SIZE(self) + growth) < 0) {
533 return -1;
534 }
535 buf = PyByteArray_AS_STRING(self);
536 /* Make the place for the additional bytes */
537 /*
538 0 lo hi old_size
539 | |<-avail->|<-----tomove------>|
540 | |<---bytes_len-->|<-----tomove------>|
541 0 lo new_hi new_size
542 */
543 memmove(buf + lo + bytes_len, buf + hi,
544 Py_SIZE(self) - lo - bytes_len);
545 }
546
547 if (bytes_len > 0)
548 memcpy(buf + lo, bytes, bytes_len);
549 return res;
472 } 550 }
473 551
474 static int 552 static int
475 bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, 553 bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
476 PyObject *values) 554 PyObject *values)
477 { 555 {
478 Py_ssize_t avail, needed; 556 Py_ssize_t needed;
479 void *bytes; 557 void *bytes;
480 Py_buffer vbytes; 558 Py_buffer vbytes;
481 int res = 0; 559 int res = 0;
482 560
483 vbytes.len = -1; 561 vbytes.len = -1;
484 if (values == (PyObject *)self) { 562 if (values == (PyObject *)self) {
485 /* Make a copy and call this function recursively */ 563 /* Make a copy and call this function recursively */
486 int err; 564 int err;
487 values = PyByteArray_FromObject(values); 565 values = PyByteArray_FromObject(values);
488 if (values == NULL) 566 if (values == NULL)
489 return -1; 567 return -1;
490 err = bytearray_setslice(self, lo, hi, values); 568 err = bytearray_setslice(self, lo, hi, values);
491 Py_DECREF(values); 569 Py_DECREF(values);
492 return err; 570 return err;
493 } 571 }
494 if (values == NULL) { 572 if (values == NULL) {
495 /* del b[lo:hi] */ 573 /* del b[lo:hi] */
496 bytes = NULL; 574 bytes = NULL;
497 needed = 0; 575 needed = 0;
498 } 576 }
499 else { 577 else {
500 if (_getbuffer(values, &vbytes) < 0) { 578 if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
501 PyErr_Format(PyExc_TypeError, 579 PyErr_Format(PyExc_TypeError,
502 "can't set bytearray slice from %.100s", 580 "can't set bytearray slice from %.100s",
503 Py_TYPE(values)->tp_name); 581 Py_TYPE(values)->tp_name);
504 return -1; 582 return -1;
505 } 583 }
506 needed = vbytes.len; 584 needed = vbytes.len;
507 bytes = vbytes.buf; 585 bytes = vbytes.buf;
508 } 586 }
509 587
510 if (lo < 0) 588 if (lo < 0)
511 lo = 0; 589 lo = 0;
512 if (hi < lo) 590 if (hi < lo)
513 hi = lo; 591 hi = lo;
514 if (hi > Py_SIZE(self)) 592 if (hi > Py_SIZE(self))
515 hi = Py_SIZE(self); 593 hi = Py_SIZE(self);
516 594
517 avail = hi - lo; 595 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
518 if (avail < 0)
519 lo = hi = avail = 0;
520
521 if (avail != needed) {
522 if (avail > needed) {
523 if (!_canresize(self)) {
524 res = -1;
525 goto finish;
526 }
527 /*
528 0 lo hi old_size
529 | |<----avail----->|<-----tomove------>|
530 | |<-needed->|<-----tomove------>|
531 0 lo new_hi new_size
532 */
533 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
534 Py_SIZE(self) - hi);
535 }
536 /* XXX(nnorwitz): need to verify this can't overflow! */
537 if (PyByteArray_Resize((PyObject *)self,
538 Py_SIZE(self) + needed - avail) < 0) {
539 res = -1;
540 goto finish;
541 }
542 if (avail < needed) {
543 /*
544 0 lo hi old_size
545 | |<-avail->|<-----tomove------>|
546 | |<----needed---->|<-----tomove------>|
547 0 lo new_hi new_size
548 */
549 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
550 Py_SIZE(self) - lo - needed);
551 }
552 }
553
554 if (needed > 0)
555 memcpy(self->ob_bytes + lo, bytes, needed);
556
557
558 finish:
559 if (vbytes.len != -1) 596 if (vbytes.len != -1)
560 PyBuffer_Release(&vbytes); 597 PyBuffer_Release(&vbytes);
561 return res; 598 return res;
562 } 599 }
563 600
564 static int 601 static int
565 bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value) 602 bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
566 { 603 {
567 int ival; 604 int ival;
568 605
569 if (i < 0) 606 if (i < 0)
570 i += Py_SIZE(self); 607 i += Py_SIZE(self);
571 608
572 if (i < 0 || i >= Py_SIZE(self)) { 609 if (i < 0 || i >= Py_SIZE(self)) {
573 PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); 610 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
574 return -1; 611 return -1;
575 } 612 }
576 613
577 if (value == NULL) 614 if (value == NULL)
578 return bytearray_setslice(self, i, i+1, NULL); 615 return bytearray_setslice(self, i, i+1, NULL);
579 616
580 if (!_getbytevalue(value, &ival)) 617 if (!_getbytevalue(value, &ival))
581 return -1; 618 return -1;
582 619
583 self->ob_bytes[i] = ival; 620 PyByteArray_AS_STRING(self)[i] = ival;
584 return 0; 621 return 0;
585 } 622 }
586 623
587 static int 624 static int
588 bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu es) 625 bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu es)
589 { 626 {
590 Py_ssize_t start, stop, step, slicelen, needed; 627 Py_ssize_t start, stop, step, slicelen, needed;
591 char *bytes; 628 char *buf, *bytes;
629 buf = PyByteArray_AS_STRING(self);
592 630
593 if (PyIndex_Check(index)) { 631 if (PyIndex_Check(index)) {
594 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError); 632 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
595 633
596 if (i == -1 && PyErr_Occurred()) 634 if (i == -1 && PyErr_Occurred())
597 return -1; 635 return -1;
598 636
599 if (i < 0) 637 if (i < 0)
600 i += PyByteArray_GET_SIZE(self); 638 i += PyByteArray_GET_SIZE(self);
601 639
602 if (i < 0 || i >= Py_SIZE(self)) { 640 if (i < 0 || i >= Py_SIZE(self)) {
603 PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); 641 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
604 return -1; 642 return -1;
605 } 643 }
606 644
607 if (values == NULL) { 645 if (values == NULL) {
608 /* Fall through to slice assignment */ 646 /* Fall through to slice assignment */
609 start = i; 647 start = i;
610 stop = i + 1; 648 stop = i + 1;
611 step = 1; 649 step = 1;
612 slicelen = 1; 650 slicelen = 1;
613 } 651 }
614 else { 652 else {
615 int ival; 653 int ival;
616 if (!_getbytevalue(values, &ival)) 654 if (!_getbytevalue(values, &ival))
617 return -1; 655 return -1;
618 self->ob_bytes[i] = (char)ival; 656 buf[i] = (char)ival;
619 return 0; 657 return 0;
620 } 658 }
621 } 659 }
622 else if (PySlice_Check(index)) { 660 else if (PySlice_Check(index)) {
623 if (PySlice_GetIndicesEx((PySliceObject *)index, 661 if (PySlice_GetIndicesEx(index,
624 PyByteArray_GET_SIZE(self), 662 PyByteArray_GET_SIZE(self),
625 &start, &stop, &step, &slicelen) < 0) { 663 &start, &stop, &step, &slicelen) < 0) {
626 return -1; 664 return -1;
627 } 665 }
628 } 666 }
629 else { 667 else {
630 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer"); 668 PyErr_Format(PyExc_TypeError,
669 "bytearray indices must be integers or slices, not %.200s",
670 Py_TYPE(index)->tp_name);
631 return -1; 671 return -1;
632 } 672 }
633 673
634 if (values == NULL) { 674 if (values == NULL) {
635 bytes = NULL; 675 bytes = NULL;
636 needed = 0; 676 needed = 0;
637 } 677 }
638 else if (values == (PyObject *)self || !PyByteArray_Check(values)) { 678 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
639 int err; 679 int err;
640 if (PyNumber_Check(values) || PyUnicode_Check(values)) { 680 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
641 PyErr_SetString(PyExc_TypeError, 681 PyErr_SetString(PyExc_TypeError,
642 "can assign only bytes, buffers, or iterables " 682 "can assign only bytes, buffers, or iterables "
643 "of ints in range(0, 256)"); 683 "of ints in range(0, 256)");
644 return -1; 684 return -1;
645 } 685 }
646 /* Make a copy and call this function recursively */ 686 /* Make a copy and call this function recursively */
647 values = PyByteArray_FromObject(values); 687 values = PyByteArray_FromObject(values);
648 if (values == NULL) 688 if (values == NULL)
649 return -1; 689 return -1;
650 err = bytearray_ass_subscript(self, index, values); 690 err = bytearray_ass_subscript(self, index, values);
651 Py_DECREF(values); 691 Py_DECREF(values);
652 return err; 692 return err;
653 } 693 }
654 else { 694 else {
655 assert(PyByteArray_Check(values)); 695 assert(PyByteArray_Check(values));
656 bytes = ((PyByteArrayObject *)values)->ob_bytes; 696 bytes = PyByteArray_AS_STRING(values);
657 needed = Py_SIZE(values); 697 needed = Py_SIZE(values);
658 } 698 }
659 /* Make sure b[5:2] = ... inserts before 5, not before 2. */ 699 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
660 if ((step < 0 && start < stop) || 700 if ((step < 0 && start < stop) ||
661 (step > 0 && start > stop)) 701 (step > 0 && start > stop))
662 stop = start; 702 stop = start;
663 if (step == 1) { 703 if (step == 1) {
664 if (slicelen != needed) { 704 return bytearray_setslice_linear(self, start, stop, bytes, needed);
665 if (!_canresize(self))
666 return -1;
667 if (slicelen > needed) {
668 /*
669 0 start stop old_size
670 | |<---slicelen--->|<-----tomove------>|
671 | |<-needed->|<-----tomove------>|
672 0 lo new_hi new_size
673 */
674 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
675 Py_SIZE(self) - stop);
676 }
677 if (PyByteArray_Resize((PyObject *)self,
678 Py_SIZE(self) + needed - slicelen) < 0)
679 return -1;
680 if (slicelen < needed) {
681 /*
682 0 lo hi old_size
683 | |<-avail->|<-----tomove------>|
684 | |<----needed---->|<-----tomove------>|
685 0 lo new_hi new_size
686 */
687 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
688 Py_SIZE(self) - start - needed);
689 }
690 }
691
692 if (needed > 0)
693 memcpy(self->ob_bytes + start, bytes, needed);
694
695 return 0;
696 } 705 }
697 else { 706 else {
698 if (needed == 0) { 707 if (needed == 0) {
699 /* Delete slice */ 708 /* Delete slice */
700 size_t cur; 709 size_t cur;
701 Py_ssize_t i; 710 Py_ssize_t i;
702 711
703 if (!_canresize(self)) 712 if (!_canresize(self))
704 return -1; 713 return -1;
714
715 if (slicelen == 0)
716 /* Nothing to do here. */
717 return 0;
718
705 if (step < 0) { 719 if (step < 0) {
706 stop = start + 1; 720 stop = start + 1;
707 start = stop + step * (slicelen - 1) - 1; 721 start = stop + step * (slicelen - 1) - 1;
708 step = -step; 722 step = -step;
709 } 723 }
710 for (cur = start, i = 0; 724 for (cur = start, i = 0;
711 i < slicelen; cur += step, i++) { 725 i < slicelen; cur += step, i++) {
712 Py_ssize_t lim = step - 1; 726 Py_ssize_t lim = step - 1;
713 727
714 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self)) 728 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
715 lim = PyByteArray_GET_SIZE(self) - cur - 1; 729 lim = PyByteArray_GET_SIZE(self) - cur - 1;
716 730
717 memmove(self->ob_bytes + cur - i, 731 memmove(buf + cur - i,
718 self->ob_bytes + cur + 1, lim); 732 buf + cur + 1, lim);
719 } 733 }
720 /* Move the tail of the bytes, in one chunk */ 734 /* Move the tail of the bytes, in one chunk */
721 cur = start + slicelen*step; 735 cur = start + (size_t)slicelen*step;
722 if (cur < (size_t)PyByteArray_GET_SIZE(self)) { 736 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
723 memmove(self->ob_bytes + cur - slicelen, 737 memmove(buf + cur - slicelen,
724 self->ob_bytes + cur, 738 buf + cur,
725 PyByteArray_GET_SIZE(self) - cur); 739 PyByteArray_GET_SIZE(self) - cur);
726 } 740 }
727 if (PyByteArray_Resize((PyObject *)self, 741 if (PyByteArray_Resize((PyObject *)self,
728 PyByteArray_GET_SIZE(self) - slicelen) < 0) 742 PyByteArray_GET_SIZE(self) - slicelen) < 0)
729 return -1; 743 return -1;
730 744
731 return 0; 745 return 0;
732 } 746 }
733 else { 747 else {
734 /* Assign slice */ 748 /* Assign slice */
735 Py_ssize_t cur, i; 749 Py_ssize_t i;
750 size_t cur;
736 751
737 if (needed != slicelen) { 752 if (needed != slicelen) {
738 PyErr_Format(PyExc_ValueError, 753 PyErr_Format(PyExc_ValueError,
739 "attempt to assign bytes of size %zd " 754 "attempt to assign bytes of size %zd "
740 "to extended slice of size %zd", 755 "to extended slice of size %zd",
741 needed, slicelen); 756 needed, slicelen);
742 return -1; 757 return -1;
743 } 758 }
744 for (cur = start, i = 0; i < slicelen; cur += step, i++) 759 for (cur = start, i = 0; i < slicelen; cur += step, i++)
745 self->ob_bytes[cur] = bytes[i]; 760 buf[cur] = bytes[i];
746 return 0; 761 return 0;
747 } 762 }
748 } 763 }
749 } 764 }
750 765
751 static int 766 static int
752 bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) 767 bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
753 { 768 {
754 static char *kwlist[] = {"source", "encoding", "errors", 0}; 769 static char *kwlist[] = {"source", "encoding", "errors", 0};
755 PyObject *arg = NULL; 770 PyObject *arg = NULL;
(...skipping 17 matching lines...) Expand all
773 /* Make a quick exit if no first argument */ 788 /* Make a quick exit if no first argument */
774 if (arg == NULL) { 789 if (arg == NULL) {
775 if (encoding != NULL || errors != NULL) { 790 if (encoding != NULL || errors != NULL) {
776 PyErr_SetString(PyExc_TypeError, 791 PyErr_SetString(PyExc_TypeError,
777 "encoding or errors without sequence argument"); 792 "encoding or errors without sequence argument");
778 return -1; 793 return -1;
779 } 794 }
780 return 0; 795 return 0;
781 } 796 }
782 797
783 if (PyBytes_Check(arg)) {
784 PyObject *new, *encoded;
785 if (encoding != NULL) {
786 encoded = _PyCodec_EncodeText(arg, encoding, errors);
787 if (encoded == NULL)
788 return -1;
789 assert(PyBytes_Check(encoded));
790 }
791 else {
792 encoded = arg;
793 Py_INCREF(arg);
794 }
795 new = bytearray_iconcat(self, arg);
796 Py_DECREF(encoded);
797 if (new == NULL)
798 return -1;
799 Py_DECREF(new);
800 return 0;
801 }
802
803 #ifdef Py_USING_UNICODE
804 if (PyUnicode_Check(arg)) { 798 if (PyUnicode_Check(arg)) {
805 /* Encode via the codec registry */ 799 /* Encode via the codec registry */
806 PyObject *encoded, *new; 800 PyObject *encoded, *new;
807 if (encoding == NULL) { 801 if (encoding == NULL) {
808 PyErr_SetString(PyExc_TypeError, 802 PyErr_SetString(PyExc_TypeError,
809 "unicode argument without an encoding"); 803 "string argument without an encoding");
810 return -1; 804 return -1;
811 } 805 }
812 encoded = _PyCodec_EncodeText(arg, encoding, errors); 806 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
813 if (encoded == NULL) 807 if (encoded == NULL)
814 return -1; 808 return -1;
815 assert(PyBytes_Check(encoded)); 809 assert(PyBytes_Check(encoded));
816 new = bytearray_iconcat(self, encoded); 810 new = bytearray_iconcat(self, encoded);
817 Py_DECREF(encoded); 811 Py_DECREF(encoded);
818 if (new == NULL) 812 if (new == NULL)
819 return -1; 813 return -1;
820 Py_DECREF(new); 814 Py_DECREF(new);
821 return 0; 815 return 0;
822 } 816 }
823 #endif
824 817
825 /* If it's not unicode, there can't be encoding or errors */ 818 /* If it's not unicode, there can't be encoding or errors */
826 if (encoding != NULL || errors != NULL) { 819 if (encoding != NULL || errors != NULL) {
827 PyErr_SetString(PyExc_TypeError, 820 PyErr_SetString(PyExc_TypeError,
828 "encoding or errors without a string argument"); 821 "encoding or errors without a string argument");
829 return -1; 822 return -1;
830 } 823 }
831 824
832 /* Is it an int? */ 825 /* Is it an int? */
833 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError); 826 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
834 if (count == -1 && PyErr_Occurred()) { 827 if (count == -1 && PyErr_Occurred()) {
835 if (PyErr_ExceptionMatches(PyExc_OverflowError)) 828 if (PyErr_ExceptionMatches(PyExc_OverflowError))
836 return -1; 829 return -1;
837 PyErr_Clear(); 830 PyErr_Clear();
838 } 831 }
839 else if (count < 0) { 832 else if (count < 0) {
840 PyErr_SetString(PyExc_ValueError, "negative count"); 833 PyErr_SetString(PyExc_ValueError, "negative count");
841 return -1; 834 return -1;
842 } 835 }
843 else { 836 else {
844 if (count > 0) { 837 if (count > 0) {
845 if (PyByteArray_Resize((PyObject *)self, count)) 838 if (PyByteArray_Resize((PyObject *)self, count))
846 return -1; 839 return -1;
847 memset(self->ob_bytes, 0, count); 840 memset(PyByteArray_AS_STRING(self), 0, count);
848 } 841 }
849 return 0; 842 return 0;
850 } 843 }
851 844
852 /* Use the buffer API */ 845 /* Use the buffer API */
853 if (PyObject_CheckBuffer(arg)) { 846 if (PyObject_CheckBuffer(arg)) {
854 Py_ssize_t size; 847 Py_ssize_t size;
855 Py_buffer view; 848 Py_buffer view;
856 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0) 849 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
857 return -1; 850 return -1;
858 size = view.len; 851 size = view.len;
859 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail; 852 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
860 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0) 853 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
861 goto fail; 854 &view, size, 'C') < 0)
855 goto fail;
862 PyBuffer_Release(&view); 856 PyBuffer_Release(&view);
863 return 0; 857 return 0;
864 fail: 858 fail:
865 PyBuffer_Release(&view); 859 PyBuffer_Release(&view);
866 return -1; 860 return -1;
867 } 861 }
868 862
869 /* XXX Optimize this if the arguments is a list, tuple */ 863 /* XXX Optimize this if the arguments is a list, tuple */
870 864
871 /* Get the iterator */ 865 /* Get the iterator */
(...skipping 18 matching lines...) Expand all
890 break; 884 break;
891 } 885 }
892 886
893 /* Interpret it as an int (__index__) */ 887 /* Interpret it as an int (__index__) */
894 rc = _getbytevalue(item, &value); 888 rc = _getbytevalue(item, &value);
895 Py_DECREF(item); 889 Py_DECREF(item);
896 if (!rc) 890 if (!rc)
897 goto error; 891 goto error;
898 892
899 /* Append the byte */ 893 /* Append the byte */
900 if (Py_SIZE(self) < self->ob_alloc) 894 if (Py_SIZE(self) + 1 < self->ob_alloc) {
901 Py_SIZE(self)++; 895 Py_SIZE(self)++;
896 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
897 }
902 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0) 898 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
903 goto error; 899 goto error;
904 self->ob_bytes[Py_SIZE(self)-1] = value; 900 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
905 } 901 }
906 902
907 /* Clean up and return success */ 903 /* Clean up and return success */
908 Py_DECREF(it); 904 Py_DECREF(it);
909 return 0; 905 return 0;
910 906
911 error: 907 error:
912 /* Error handling when it != NULL */ 908 /* Error handling when it != NULL */
913 Py_DECREF(it); 909 Py_DECREF(it);
914 return -1; 910 return -1;
915 } 911 }
916 912
917 /* Mostly copied from string_repr, but without the 913 /* Mostly copied from string_repr, but without the
918 "smart quote" functionality. */ 914 "smart quote" functionality. */
919 static PyObject * 915 static PyObject *
920 bytearray_repr(PyByteArrayObject *self) 916 bytearray_repr(PyByteArrayObject *self)
921 { 917 {
922 static const char *hexdigits = "0123456789abcdef";
923 const char *quote_prefix = "bytearray(b"; 918 const char *quote_prefix = "bytearray(b";
924 const char *quote_postfix = ")"; 919 const char *quote_postfix = ")";
925 Py_ssize_t length = Py_SIZE(self); 920 Py_ssize_t length = Py_SIZE(self);
926 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */ 921 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
927 size_t newsize; 922 size_t newsize;
928 PyObject *v; 923 PyObject *v;
929 if (length > (PY_SSIZE_T_MAX - 14) / 4) { 924 Py_ssize_t i;
925 char *bytes;
926 char c;
927 char *p;
928 int quote;
929 char *test, *start;
930 char *buffer;
931
932 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
930 PyErr_SetString(PyExc_OverflowError, 933 PyErr_SetString(PyExc_OverflowError,
931 "bytearray object is too large to make repr"); 934 "bytearray object is too large to make repr");
932 return NULL; 935 return NULL;
933 } 936 }
934 newsize = 14 + 4 * length; 937
935 v = PyString_FromStringAndSize(NULL, newsize); 938 newsize = 15 + length * 4;
936 if (v == NULL) { 939 buffer = PyObject_Malloc(newsize);
937 return NULL; 940 if (buffer == NULL) {
938 } 941 PyErr_NoMemory();
939 else { 942 return NULL;
940 register Py_ssize_t i; 943 }
941 register char c; 944
942 register char *p; 945 /* Figure out which quote to use; single is preferred */
943 int quote; 946 quote = '\'';
944 947 start = PyByteArray_AS_STRING(self);
945 /* Figure out which quote to use; single is preferred */ 948 for (test = start; test < start+length; ++test) {
946 quote = '\''; 949 if (*test == '"') {
947 { 950 quote = '\''; /* back to single */
948 char *test, *start; 951 break;
949 start = PyByteArray_AS_STRING(self); 952 }
950 for (test = start; test < start+length; ++test) { 953 else if (*test == '\'')
951 if (*test == '"') { 954 quote = '"';
952 quote = '\''; /* back to single */ 955 }
953 goto decided; 956
954 } 957 p = buffer;
955 else if (*test == '\'') 958 while (*quote_prefix)
956 quote = '"'; 959 *p++ = *quote_prefix++;
957 } 960 *p++ = quote;
958 decided: 961
959 ; 962 bytes = PyByteArray_AS_STRING(self);
960 } 963 for (i = 0; i < length; i++) {
961 964 /* There's at least enough room for a hex escape
962 p = PyString_AS_STRING(v); 965 and a closing quote. */
963 while (*quote_prefix) 966 assert(newsize - (p - buffer) >= 5);
964 *p++ = *quote_prefix++; 967 c = bytes[i];
965 *p++ = quote; 968 if (c == '\'' || c == '\\')
966 969 *p++ = '\\', *p++ = c;
967 for (i = 0; i < length; i++) { 970 else if (c == '\t')
968 /* There's at least enough room for a hex escape 971 *p++ = '\\', *p++ = 't';
969 and a closing quote. */ 972 else if (c == '\n')
970 assert(newsize - (p - PyString_AS_STRING(v)) >= 5); 973 *p++ = '\\', *p++ = 'n';
971 c = self->ob_bytes[i]; 974 else if (c == '\r')
972 if (c == '\'' || c == '\\') 975 *p++ = '\\', *p++ = 'r';
973 *p++ = '\\', *p++ = c; 976 else if (c == 0)
974 else if (c == '\t') 977 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
975 *p++ = '\\', *p++ = 't'; 978 else if (c < ' ' || c >= 0x7f) {
976 else if (c == '\n') 979 *p++ = '\\';
977 *p++ = '\\', *p++ = 'n'; 980 *p++ = 'x';
978 else if (c == '\r') 981 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
979 *p++ = '\\', *p++ = 'r'; 982 *p++ = Py_hexdigits[c & 0xf];
980 else if (c == 0) 983 }
981 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0'; 984 else
982 else if (c < ' ' || c >= 0x7f) { 985 *p++ = c;
983 *p++ = '\\'; 986 }
984 *p++ = 'x'; 987 assert(newsize - (p - buffer) >= 1);
985 *p++ = hexdigits[(c & 0xf0) >> 4]; 988 *p++ = quote;
986 *p++ = hexdigits[c & 0xf]; 989 while (*quote_postfix) {
987 } 990 *p++ = *quote_postfix++;
988 else 991 }
989 *p++ = c; 992
990 } 993 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
991 assert(newsize - (p - PyString_AS_STRING(v)) >= 1); 994 PyObject_Free(buffer);
992 *p++ = quote; 995 return v;
993 while (*quote_postfix) {
994 *p++ = *quote_postfix++;
995 }
996 *p = '\0';
997 /* v is cleared on error */
998 (void)_PyString_Resize(&v, (p - PyString_AS_STRING(v)));
999 return v;
1000 }
1001 } 996 }
1002 997
1003 static PyObject * 998 static PyObject *
1004 bytearray_str(PyObject *op) 999 bytearray_str(PyObject *op)
1005 { 1000 {
1006 #if 0 1001 if (Py_BytesWarningFlag) {
1007 if (Py_BytesWarningFlag) { 1002 if (PyErr_WarnEx(PyExc_BytesWarning,
1008 if (PyErr_WarnEx(PyExc_BytesWarning, 1003 "str() on a bytearray instance", 1))
1009 "str() on a bytearray instance", 1)) 1004 return NULL;
1010 return NULL; 1005 }
1011 } 1006 return bytearray_repr((PyByteArrayObject*)op);
1012 return bytearray_repr((PyByteArrayObject*)op);
1013 #endif
1014 return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE (op));
1015 } 1007 }
1016 1008
1017 static PyObject * 1009 static PyObject *
1018 bytearray_richcompare(PyObject *self, PyObject *other, int op) 1010 bytearray_richcompare(PyObject *self, PyObject *other, int op)
1019 { 1011 {
1020 Py_ssize_t self_size, other_size; 1012 Py_ssize_t self_size, other_size;
1021 Py_buffer self_bytes, other_bytes; 1013 Py_buffer self_bytes, other_bytes;
1022 PyObject *res; 1014 PyObject *res;
1023 Py_ssize_t minsize; 1015 Py_ssize_t minsize;
1024 int cmp, rc; 1016 int cmp, rc;
1025 1017
1026 /* Bytes can be compared to anything that supports the (binary) 1018 /* Bytes can be compared to anything that supports the (binary)
1027 buffer API. Except that a comparison with Unicode is always an 1019 buffer API. Except that a comparison with Unicode is always an
1028 error, even if the comparison is for equality. */ 1020 error, even if the comparison is for equality. */
1029 #ifdef Py_USING_UNICODE
1030 rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type); 1021 rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type);
1031 if (!rc) 1022 if (!rc)
1032 rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type); 1023 rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type);
1033 if (rc < 0) 1024 if (rc < 0)
1034 return NULL; 1025 return NULL;
1035 if (rc) { 1026 if (rc) {
1036 if (Py_BytesWarningFlag && op == Py_EQ) { 1027 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
1037 if (PyErr_WarnEx(PyExc_BytesWarning, 1028 if (PyErr_WarnEx(PyExc_BytesWarning,
1038 "Comparison between bytearray and string", 1)) 1029 "Comparison between bytearray and string", 1))
1039 return NULL; 1030 return NULL;
1040 } 1031 }
1041 1032
1042 Py_INCREF(Py_NotImplemented); 1033 Py_RETURN_NOTIMPLEMENTED;
1043 return Py_NotImplemented; 1034 }
1044 } 1035
1045 #endif 1036 if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
1046
1047 self_size = _getbuffer(self, &self_bytes);
1048 if (self_size < 0) {
1049 PyErr_Clear(); 1037 PyErr_Clear();
1050 Py_INCREF(Py_NotImplemented); 1038 Py_RETURN_NOTIMPLEMENTED;
1051 return Py_NotImplemented; 1039 }
1052 } 1040 self_size = self_bytes.len;
1053 1041
1054 other_size = _getbuffer(other, &other_bytes); 1042 if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
1055 if (other_size < 0) {
1056 PyErr_Clear(); 1043 PyErr_Clear();
1057 PyBuffer_Release(&self_bytes); 1044 PyBuffer_Release(&self_bytes);
1058 Py_INCREF(Py_NotImplemented); 1045 Py_RETURN_NOTIMPLEMENTED;
1059 return Py_NotImplemented; 1046 }
1060 } 1047 other_size = other_bytes.len;
1061 1048
1062 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) { 1049 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1063 /* Shortcut: if the lengths differ, the objects differ */ 1050 /* Shortcut: if the lengths differ, the objects differ */
1064 cmp = (op == Py_NE); 1051 cmp = (op == Py_NE);
1065 } 1052 }
1066 else { 1053 else {
1067 minsize = self_size; 1054 minsize = self_size;
1068 if (other_size < minsize) 1055 if (other_size < minsize)
1069 minsize = other_size; 1056 minsize = other_size;
1070 1057
(...skipping 26 matching lines...) Expand all
1097 1084
1098 static void 1085 static void
1099 bytearray_dealloc(PyByteArrayObject *self) 1086 bytearray_dealloc(PyByteArrayObject *self)
1100 { 1087 {
1101 if (self->ob_exports > 0) { 1088 if (self->ob_exports > 0) {
1102 PyErr_SetString(PyExc_SystemError, 1089 PyErr_SetString(PyExc_SystemError,
1103 "deallocated bytearray object has exported buffers"); 1090 "deallocated bytearray object has exported buffers");
1104 PyErr_Print(); 1091 PyErr_Print();
1105 } 1092 }
1106 if (self->ob_bytes != 0) { 1093 if (self->ob_bytes != 0) {
1107 PyMem_Free(self->ob_bytes); 1094 PyObject_Free(self->ob_bytes);
1108 } 1095 }
1109 Py_TYPE(self)->tp_free((PyObject *)self); 1096 Py_TYPE(self)->tp_free((PyObject *)self);
1110 } 1097 }
1111 1098
1112 1099
1113 /* -------------------------------------------------------------------- */ 1100 /* -------------------------------------------------------------------- */
1114 /* Methods */ 1101 /* Methods */
1115 1102
1103 #define FASTSEARCH fastsearch
1104 #define STRINGLIB(F) stringlib_##F
1116 #define STRINGLIB_CHAR char 1105 #define STRINGLIB_CHAR char
1106 #define STRINGLIB_SIZEOF_CHAR 1
1117 #define STRINGLIB_LEN PyByteArray_GET_SIZE 1107 #define STRINGLIB_LEN PyByteArray_GET_SIZE
1118 #define STRINGLIB_STR PyByteArray_AS_STRING 1108 #define STRINGLIB_STR PyByteArray_AS_STRING
1119 #define STRINGLIB_NEW PyByteArray_FromStringAndSize 1109 #define STRINGLIB_NEW PyByteArray_FromStringAndSize
1120 #define STRINGLIB_ISSPACE Py_ISSPACE 1110 #define STRINGLIB_ISSPACE Py_ISSPACE
1121 #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r')) 1111 #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
1122 #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact 1112 #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1123 #define STRINGLIB_MUTABLE 1 1113 #define STRINGLIB_MUTABLE 1
1124 1114
1125 #include "stringlib/fastsearch.h" 1115 #include "stringlib/fastsearch.h"
1126 #include "stringlib/count.h" 1116 #include "stringlib/count.h"
1127 #include "stringlib/find.h" 1117 #include "stringlib/find.h"
1118 #include "stringlib/join.h"
1128 #include "stringlib/partition.h" 1119 #include "stringlib/partition.h"
1129 #include "stringlib/split.h" 1120 #include "stringlib/split.h"
1130 #include "stringlib/ctype.h" 1121 #include "stringlib/ctype.h"
1131 #include "stringlib/transmogrify.h" 1122 #include "stringlib/transmogrify.h"
1132 1123
1133 1124
1134 /* The following Py_LOCAL_INLINE and Py_LOCAL functions 1125 /* The following Py_LOCAL_INLINE and Py_LOCAL functions
1135 were copied from the old char* style string object. */ 1126 were copied from the old char* style string object. */
1136 1127
1137 /* helper macro to fixup start/end slice values */ 1128 /* helper macro to fixup start/end slice values */
1138 #define ADJUST_INDICES(start, end, len) \ 1129 #define ADJUST_INDICES(start, end, len) \
1139 if (end > len) \ 1130 if (end > len) \
1140 end = len; \ 1131 end = len; \
1141 else if (end < 0) { \ 1132 else if (end < 0) { \
1142 end += len; \ 1133 end += len; \
1143 if (end < 0) \ 1134 if (end < 0) \
1144 end = 0; \ 1135 end = 0; \
1145 } \ 1136 } \
1146 if (start < 0) { \ 1137 if (start < 0) { \
1147 start += len; \ 1138 start += len; \
1148 if (start < 0) \ 1139 if (start < 0) \
1149 start = 0; \ 1140 start = 0; \
1150 } 1141 }
1151 1142
1152 Py_LOCAL_INLINE(Py_ssize_t) 1143 Py_LOCAL_INLINE(Py_ssize_t)
1153 bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir) 1144 bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
1154 { 1145 {
1155 PyObject *subobj; 1146 PyObject *subobj;
1147 char byte;
1156 Py_buffer subbuf; 1148 Py_buffer subbuf;
1149 const char *sub;
1150 Py_ssize_t len, sub_len;
1157 Py_ssize_t start=0, end=PY_SSIZE_T_MAX; 1151 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1158 Py_ssize_t res; 1152 Py_ssize_t res;
1159 1153
1160 if (!stringlib_parse_args_finds("find/rfind/index/rindex", 1154 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1161 args, &subobj, &start, &end)) 1155 args, &subobj, &byte, &start, &end))
1162 return -2; 1156 return -2;
1163 if (_getbuffer(subobj, &subbuf) < 0) 1157
1164 return -2; 1158 if (subobj) {
1165 if (dir > 0) 1159 if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
1166 res = stringlib_find_slice( 1160 return -2;
1167 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), 1161
1168 subbuf.buf, subbuf.len, start, end); 1162 sub = subbuf.buf;
1169 else 1163 sub_len = subbuf.len;
1170 res = stringlib_rfind_slice( 1164 }
1171 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), 1165 else {
1172 subbuf.buf, subbuf.len, start, end); 1166 sub = &byte;
1173 PyBuffer_Release(&subbuf); 1167 sub_len = 1;
1168 }
1169 len = PyByteArray_GET_SIZE(self);
1170
1171 ADJUST_INDICES(start, end, len);
1172 if (end - start < sub_len)
1173 res = -1;
1174 /* Issue #23573: FIXME, windows has no memrchr() */
1175 else if (sub_len == 1 && dir > 0) {
1176 unsigned char needle = *sub;
1177 res = stringlib_fastsearch_memchr_1char(
1178 PyByteArray_AS_STRING(self) + start, end - start,
1179 needle, needle, FAST_SEARCH);
1180 if (res >= 0)
1181 res += start;
1182 }
1183 else {
1184 if (dir > 0)
1185 res = stringlib_find_slice(
1186 PyByteArray_AS_STRING(self), len,
1187 sub, sub_len, start, end);
1188 else
1189 res = stringlib_rfind_slice(
1190 PyByteArray_AS_STRING(self), len,
1191 sub, sub_len, start, end);
1192 }
1193
1194 if (subobj)
1195 PyBuffer_Release(&subbuf);
1196
1174 return res; 1197 return res;
1175 } 1198 }
1176 1199
1177 PyDoc_STRVAR(find__doc__, 1200 PyDoc_STRVAR(find__doc__,
1178 "B.find(sub [,start [,end]]) -> int\n\ 1201 "B.find(sub[, start[, end]]) -> int\n\
1179 \n\ 1202 \n\
1180 Return the lowest index in B where subsection sub is found,\n\ 1203 Return the lowest index in B where subsection sub is found,\n\
1181 such that sub is contained within B[start,end]. Optional\n\ 1204 such that sub is contained within B[start,end]. Optional\n\
1182 arguments start and end are interpreted as in slice notation.\n\ 1205 arguments start and end are interpreted as in slice notation.\n\
1183 \n\ 1206 \n\
1184 Return -1 on failure."); 1207 Return -1 on failure.");
1185 1208
1186 static PyObject * 1209 static PyObject *
1187 bytearray_find(PyByteArrayObject *self, PyObject *args) 1210 bytearray_find(PyByteArrayObject *self, PyObject *args)
1188 { 1211 {
1189 Py_ssize_t result = bytearray_find_internal(self, args, +1); 1212 Py_ssize_t result = bytearray_find_internal(self, args, +1);
1190 if (result == -2) 1213 if (result == -2)
1191 return NULL; 1214 return NULL;
1192 return PyInt_FromSsize_t(result); 1215 return PyLong_FromSsize_t(result);
1193 } 1216 }
1194 1217
1195 PyDoc_STRVAR(count__doc__, 1218 PyDoc_STRVAR(count__doc__,
1196 "B.count(sub [,start [,end]]) -> int\n\ 1219 "B.count(sub[, start[, end]]) -> int\n\
1197 \n\ 1220 \n\
1198 Return the number of non-overlapping occurrences of subsection sub in\n\ 1221 Return the number of non-overlapping occurrences of subsection sub in\n\
1199 bytes B[start:end]. Optional arguments start and end are interpreted\n\ 1222 bytes B[start:end]. Optional arguments start and end are interpreted\n\
1200 as in slice notation."); 1223 as in slice notation.");
1201 1224
1202 static PyObject * 1225 static PyObject *
1203 bytearray_count(PyByteArrayObject *self, PyObject *args) 1226 bytearray_count(PyByteArrayObject *self, PyObject *args)
1204 { 1227 {
1205 PyObject *sub_obj; 1228 PyObject *sub_obj;
1206 const char *str = PyByteArray_AS_STRING(self); 1229 const char *str = PyByteArray_AS_STRING(self), *sub;
1230 Py_ssize_t sub_len;
1231 char byte;
1207 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; 1232 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1233
1208 Py_buffer vsub; 1234 Py_buffer vsub;
1209 PyObject *count_obj; 1235 PyObject *count_obj;
1210 1236
1211 if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end)) 1237 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1212 return NULL; 1238 &start, &end))
1213 1239 return NULL;
1214 if (_getbuffer(sub_obj, &vsub) < 0) 1240
1215 return NULL; 1241 if (sub_obj) {
1242 if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
1243 return NULL;
1244
1245 sub = vsub.buf;
1246 sub_len = vsub.len;
1247 }
1248 else {
1249 sub = &byte;
1250 sub_len = 1;
1251 }
1216 1252
1217 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self)); 1253 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
1218 1254
1219 count_obj = PyInt_FromSsize_t( 1255 count_obj = PyLong_FromSsize_t(
1220 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T _MAX) 1256 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
1221 ); 1257 );
1222 PyBuffer_Release(&vsub); 1258
1259 if (sub_obj)
1260 PyBuffer_Release(&vsub);
1261
1223 return count_obj; 1262 return count_obj;
1224 } 1263 }
1225 1264
1265 /*[clinic input]
1266 bytearray.clear
1267
1268 self: self(type="PyByteArrayObject *")
1269
1270 Remove all items from the bytearray.
1271 [clinic start generated code]*/
1272
1273 static PyObject *
1274 bytearray_clear_impl(PyByteArrayObject *self)
1275 /*[clinic end generated code: output=85c2fe6aede0956c input=e524fd330abcdc18]*/
1276 {
1277 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1278 return NULL;
1279 Py_RETURN_NONE;
1280 }
1281
1282 /*[clinic input]
1283 bytearray.copy
1284
1285 self: self(type="PyByteArrayObject *")
1286
1287 Return a copy of B.
1288 [clinic start generated code]*/
1289
1290 static PyObject *
1291 bytearray_copy_impl(PyByteArrayObject *self)
1292 /*[clinic end generated code: output=68cfbcfed484c132 input=6d5d2975aa0f33f3]*/
1293 {
1294 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self) ,
1295 PyByteArray_GET_SIZE(self));
1296 }
1226 1297
1227 PyDoc_STRVAR(index__doc__, 1298 PyDoc_STRVAR(index__doc__,
1228 "B.index(sub [,start [,end]]) -> int\n\ 1299 "B.index(sub[, start[, end]]) -> int\n\
1229 \n\ 1300 \n\
1230 Like B.find() but raise ValueError when the subsection is not found."); 1301 Like B.find() but raise ValueError when the subsection is not found.");
1231 1302
1232 static PyObject * 1303 static PyObject *
1233 bytearray_index(PyByteArrayObject *self, PyObject *args) 1304 bytearray_index(PyByteArrayObject *self, PyObject *args)
1234 { 1305 {
1235 Py_ssize_t result = bytearray_find_internal(self, args, +1); 1306 Py_ssize_t result = bytearray_find_internal(self, args, +1);
1236 if (result == -2) 1307 if (result == -2)
1237 return NULL; 1308 return NULL;
1238 if (result == -1) { 1309 if (result == -1) {
1239 PyErr_SetString(PyExc_ValueError, 1310 PyErr_SetString(PyExc_ValueError,
1240 "subsection not found"); 1311 "subsection not found");
1241 return NULL; 1312 return NULL;
1242 } 1313 }
1243 return PyInt_FromSsize_t(result); 1314 return PyLong_FromSsize_t(result);
1244 } 1315 }
1245 1316
1246 1317
1247 PyDoc_STRVAR(rfind__doc__, 1318 PyDoc_STRVAR(rfind__doc__,
1248 "B.rfind(sub [,start [,end]]) -> int\n\ 1319 "B.rfind(sub[, start[, end]]) -> int\n\
1249 \n\ 1320 \n\
1250 Return the highest index in B where subsection sub is found,\n\ 1321 Return the highest index in B where subsection sub is found,\n\
1251 such that sub is contained within B[start,end]. Optional\n\ 1322 such that sub is contained within B[start,end]. Optional\n\
1252 arguments start and end are interpreted as in slice notation.\n\ 1323 arguments start and end are interpreted as in slice notation.\n\
1253 \n\ 1324 \n\
1254 Return -1 on failure."); 1325 Return -1 on failure.");
1255 1326
1256 static PyObject * 1327 static PyObject *
1257 bytearray_rfind(PyByteArrayObject *self, PyObject *args) 1328 bytearray_rfind(PyByteArrayObject *self, PyObject *args)
1258 { 1329 {
1259 Py_ssize_t result = bytearray_find_internal(self, args, -1); 1330 Py_ssize_t result = bytearray_find_internal(self, args, -1);
1260 if (result == -2) 1331 if (result == -2)
1261 return NULL; 1332 return NULL;
1262 return PyInt_FromSsize_t(result); 1333 return PyLong_FromSsize_t(result);
1263 } 1334 }
1264 1335
1265 1336
1266 PyDoc_STRVAR(rindex__doc__, 1337 PyDoc_STRVAR(rindex__doc__,
1267 "B.rindex(sub [,start [,end]]) -> int\n\ 1338 "B.rindex(sub[, start[, end]]) -> int\n\
1268 \n\ 1339 \n\
1269 Like B.rfind() but raise ValueError when the subsection is not found."); 1340 Like B.rfind() but raise ValueError when the subsection is not found.");
1270 1341
1271 static PyObject * 1342 static PyObject *
1272 bytearray_rindex(PyByteArrayObject *self, PyObject *args) 1343 bytearray_rindex(PyByteArrayObject *self, PyObject *args)
1273 { 1344 {
1274 Py_ssize_t result = bytearray_find_internal(self, args, -1); 1345 Py_ssize_t result = bytearray_find_internal(self, args, -1);
1275 if (result == -2) 1346 if (result == -2)
1276 return NULL; 1347 return NULL;
1277 if (result == -1) { 1348 if (result == -1) {
1278 PyErr_SetString(PyExc_ValueError, 1349 PyErr_SetString(PyExc_ValueError,
1279 "subsection not found"); 1350 "subsection not found");
1280 return NULL; 1351 return NULL;
1281 } 1352 }
1282 return PyInt_FromSsize_t(result); 1353 return PyLong_FromSsize_t(result);
1283 } 1354 }
1284 1355
1285 1356
1286 static int 1357 static int
1287 bytearray_contains(PyObject *self, PyObject *arg) 1358 bytearray_contains(PyObject *self, PyObject *arg)
1288 { 1359 {
1289 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); 1360 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1290 if (ival == -1 && PyErr_Occurred()) { 1361 if (ival == -1 && PyErr_Occurred()) {
1291 Py_buffer varg; 1362 Py_buffer varg;
1292 int pos; 1363 Py_ssize_t pos;
1293 PyErr_Clear(); 1364 PyErr_Clear();
1294 if (_getbuffer(arg, &varg) < 0) 1365 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
1295 return -1; 1366 return -1;
1296 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self), 1367 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1297 varg.buf, varg.len, 0); 1368 varg.buf, varg.len, 0);
1298 PyBuffer_Release(&varg); 1369 PyBuffer_Release(&varg);
1299 return pos >= 0; 1370 return pos >= 0;
1300 } 1371 }
1301 if (ival < 0 || ival >= 256) { 1372 if (ival < 0 || ival >= 256) {
1302 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); 1373 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1303 return -1; 1374 return -1;
1304 } 1375 }
1305 1376
1306 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL; 1377 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NUL L;
1307 } 1378 }
1308 1379
1309 1380
1310 /* Matches the end (direction >= 0) or start (direction < 0) of self 1381 /* Matches the end (direction >= 0) or start (direction < 0) of self
1311 * against substr, using the start and end arguments. Returns 1382 * against substr, using the start and end arguments. Returns
1312 * -1 on error, 0 if not found and 1 if found. 1383 * -1 on error, 0 if not found and 1 if found.
1313 */ 1384 */
1314 Py_LOCAL(int) 1385 Py_LOCAL(int)
1315 _bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start , 1386 _bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start ,
1316 Py_ssize_t end, int direction) 1387 Py_ssize_t end, int direction)
1317 { 1388 {
1318 Py_ssize_t len = PyByteArray_GET_SIZE(self); 1389 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1319 const char* str; 1390 const char* str;
1320 Py_buffer vsubstr; 1391 Py_buffer vsubstr;
1321 int rv = 0; 1392 int rv = 0;
1322 1393
1323 str = PyByteArray_AS_STRING(self); 1394 str = PyByteArray_AS_STRING(self);
1324 1395
1325 if (_getbuffer(substr, &vsubstr) < 0) 1396 if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0)
1326 return -1; 1397 return -1;
1327 1398
1328 ADJUST_INDICES(start, end, len); 1399 ADJUST_INDICES(start, end, len);
1329 1400
1330 if (direction < 0) { 1401 if (direction < 0) {
1331 /* startswith */ 1402 /* startswith */
1332 if (start+vsubstr.len > len) { 1403 if (start+vsubstr.len > len) {
1333 goto done; 1404 goto done;
1334 } 1405 }
1335 } else { 1406 } else {
1336 /* endswith */ 1407 /* endswith */
1337 if (end-start < vsubstr.len || start > len) { 1408 if (end-start < vsubstr.len || start > len) {
1338 goto done; 1409 goto done;
1339 } 1410 }
1340 1411
1341 if (end-vsubstr.len > start) 1412 if (end-vsubstr.len > start)
1342 start = end - vsubstr.len; 1413 start = end - vsubstr.len;
1343 } 1414 }
1344 if (end-start >= vsubstr.len) 1415 if (end-start >= vsubstr.len)
1345 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len); 1416 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1346 1417
1347 done: 1418 done:
1348 PyBuffer_Release(&vsubstr); 1419 PyBuffer_Release(&vsubstr);
1349 return rv; 1420 return rv;
1350 } 1421 }
1351 1422
1352 1423
1353 PyDoc_STRVAR(startswith__doc__, 1424 PyDoc_STRVAR(startswith__doc__,
1354 "B.startswith(prefix [,start [,end]]) -> bool\n\ 1425 "B.startswith(prefix[, start[, end]]) -> bool\n\
1355 \n\ 1426 \n\
1356 Return True if B starts with the specified prefix, False otherwise.\n\ 1427 Return True if B starts with the specified prefix, False otherwise.\n\
1357 With optional start, test B beginning at that position.\n\ 1428 With optional start, test B beginning at that position.\n\
1358 With optional end, stop comparing B at that position.\n\ 1429 With optional end, stop comparing B at that position.\n\
1359 prefix can also be a tuple of strings to try."); 1430 prefix can also be a tuple of bytes to try.");
1360 1431
1361 static PyObject * 1432 static PyObject *
1362 bytearray_startswith(PyByteArrayObject *self, PyObject *args) 1433 bytearray_startswith(PyByteArrayObject *self, PyObject *args)
1363 { 1434 {
1364 Py_ssize_t start = 0; 1435 Py_ssize_t start = 0;
1365 Py_ssize_t end = PY_SSIZE_T_MAX; 1436 Py_ssize_t end = PY_SSIZE_T_MAX;
1366 PyObject *subobj; 1437 PyObject *subobj;
1367 int result; 1438 int result;
1368 1439
1369 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end)) 1440 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
1370 return NULL; 1441 return NULL;
1371 if (PyTuple_Check(subobj)) { 1442 if (PyTuple_Check(subobj)) {
1372 Py_ssize_t i; 1443 Py_ssize_t i;
1373 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { 1444 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
1374 result = _bytearray_tailmatch(self, 1445 result = _bytearray_tailmatch(self,
1375 PyTuple_GET_ITEM(subobj, i), 1446 PyTuple_GET_ITEM(subobj, i),
1376 start, end, -1); 1447 start, end, -1);
1377 if (result == -1) 1448 if (result == -1)
1378 return NULL; 1449 return NULL;
1379 else if (result) { 1450 else if (result) {
1380 Py_RETURN_TRUE; 1451 Py_RETURN_TRUE;
1381 } 1452 }
1382 } 1453 }
1383 Py_RETURN_FALSE; 1454 Py_RETURN_FALSE;
1384 } 1455 }
1385 result = _bytearray_tailmatch(self, subobj, start, end, -1); 1456 result = _bytearray_tailmatch(self, subobj, start, end, -1);
1386 if (result == -1) 1457 if (result == -1) {
1387 return NULL; 1458 if (PyErr_ExceptionMatches(PyExc_TypeError))
1459 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1460 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name );
1461 return NULL;
1462 }
1388 else 1463 else
1389 return PyBool_FromLong(result); 1464 return PyBool_FromLong(result);
1390 } 1465 }
1391 1466
1392 PyDoc_STRVAR(endswith__doc__, 1467 PyDoc_STRVAR(endswith__doc__,
1393 "B.endswith(suffix [,start [,end]]) -> bool\n\ 1468 "B.endswith(suffix[, start[, end]]) -> bool\n\
1394 \n\ 1469 \n\
1395 Return True if B ends with the specified suffix, False otherwise.\n\ 1470 Return True if B ends with the specified suffix, False otherwise.\n\
1396 With optional start, test B beginning at that position.\n\ 1471 With optional start, test B beginning at that position.\n\
1397 With optional end, stop comparing B at that position.\n\ 1472 With optional end, stop comparing B at that position.\n\
1398 suffix can also be a tuple of strings to try."); 1473 suffix can also be a tuple of bytes to try.");
1399 1474
1400 static PyObject * 1475 static PyObject *
1401 bytearray_endswith(PyByteArrayObject *self, PyObject *args) 1476 bytearray_endswith(PyByteArrayObject *self, PyObject *args)
1402 { 1477 {
1403 Py_ssize_t start = 0; 1478 Py_ssize_t start = 0;
1404 Py_ssize_t end = PY_SSIZE_T_MAX; 1479 Py_ssize_t end = PY_SSIZE_T_MAX;
1405 PyObject *subobj; 1480 PyObject *subobj;
1406 int result; 1481 int result;
1407 1482
1408 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end)) 1483 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
1409 return NULL; 1484 return NULL;
1410 if (PyTuple_Check(subobj)) { 1485 if (PyTuple_Check(subobj)) {
1411 Py_ssize_t i; 1486 Py_ssize_t i;
1412 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { 1487 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
1413 result = _bytearray_tailmatch(self, 1488 result = _bytearray_tailmatch(self,
1414 PyTuple_GET_ITEM(subobj, i), 1489 PyTuple_GET_ITEM(subobj, i),
1415 start, end, +1); 1490 start, end, +1);
1416 if (result == -1) 1491 if (result == -1)
1417 return NULL; 1492 return NULL;
1418 else if (result) { 1493 else if (result) {
1419 Py_RETURN_TRUE; 1494 Py_RETURN_TRUE;
1420 } 1495 }
1421 } 1496 }
1422 Py_RETURN_FALSE; 1497 Py_RETURN_FALSE;
1423 } 1498 }
1424 result = _bytearray_tailmatch(self, subobj, start, end, +1); 1499 result = _bytearray_tailmatch(self, subobj, start, end, +1);
1425 if (result == -1) 1500 if (result == -1) {
1426 return NULL; 1501 if (PyErr_ExceptionMatches(PyExc_TypeError))
1502 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1503 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
1504 return NULL;
1505 }
1427 else 1506 else
1428 return PyBool_FromLong(result); 1507 return PyBool_FromLong(result);
1429 } 1508 }
1430 1509
1431 1510
1432 PyDoc_STRVAR(translate__doc__, 1511 /*[clinic input]
1433 "B.translate(table[, deletechars]) -> bytearray\n\ 1512 bytearray.translate
1434 \n\ 1513
1435 Return a copy of B, where all characters occurring in the\n\ 1514 self: self(type="PyByteArrayObject *")
1436 optional argument deletechars are removed, and the remaining\n\ 1515 table: object
1437 characters have been mapped through the given translation\n\ 1516 Translation table, which must be a bytes object of length 256.
1438 table, which must be a bytes object of length 256."); 1517 [
1439 1518 deletechars: object
1440 static PyObject * 1519 ]
1441 bytearray_translate(PyByteArrayObject *self, PyObject *args) 1520 /
1442 { 1521
1443 register char *input, *output; 1522 Return a copy with each character mapped by the given translation table.
1444 register const char *table; 1523
1445 register Py_ssize_t i, c; 1524 All characters occurring in the optional argument deletechars are removed.
1525 The remaining characters are mapped through the given translation table.
1526 [clinic start generated code]*/
1527
1528 static PyObject *
1529 bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
1530 int group_right_1, PyObject *deletechars)
1531 /*[clinic end generated code: output=2bebc86a9a1ff083 input=b749ad85f4860824]*/
1532 {
1533 char *input, *output;
1534 const char *table_chars;
1535 Py_ssize_t i, c;
1446 PyObject *input_obj = (PyObject*)self; 1536 PyObject *input_obj = (PyObject*)self;
1447 const char *output_start; 1537 const char *output_start;
1448 Py_ssize_t inlen; 1538 Py_ssize_t inlen;
1449 PyObject *result = NULL; 1539 PyObject *result = NULL;
1450 int trans_table[256]; 1540 int trans_table[256];
1451 PyObject *tableobj = NULL, *delobj = NULL;
1452 Py_buffer vtable, vdel; 1541 Py_buffer vtable, vdel;
1453 1542
1454 if (!PyArg_UnpackTuple(args, "translate", 1, 2, 1543 if (table == Py_None) {
1455 &tableobj, &delobj)) 1544 table_chars = NULL;
1456 return NULL;
1457
1458 if (tableobj == Py_None) {
1459 table = NULL; 1545 table = NULL;
1460 tableobj = NULL; 1546 } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
1461 } else if (_getbuffer(tableobj, &vtable) < 0) {
1462 return NULL; 1547 return NULL;
1463 } else { 1548 } else {
1464 if (vtable.len != 256) { 1549 if (vtable.len != 256) {
1465 PyErr_SetString(PyExc_ValueError, 1550 PyErr_SetString(PyExc_ValueError,
1466 "translation table must be 256 characters long"); 1551 "translation table must be 256 characters long");
1467 PyBuffer_Release(&vtable); 1552 PyBuffer_Release(&vtable);
1468 return NULL; 1553 return NULL;
1469 } 1554 }
1470 table = (const char*)vtable.buf; 1555 table_chars = (const char*)vtable.buf;
1471 } 1556 }
1472 1557
1473 if (delobj != NULL) { 1558 if (deletechars != NULL) {
1474 if (_getbuffer(delobj, &vdel) < 0) { 1559 if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
1475 if (tableobj != NULL) 1560 if (table != NULL)
1476 PyBuffer_Release(&vtable); 1561 PyBuffer_Release(&vtable);
1477 return NULL; 1562 return NULL;
1478 } 1563 }
1479 } 1564 }
1480 else { 1565 else {
1481 vdel.buf = NULL; 1566 vdel.buf = NULL;
1482 vdel.len = 0; 1567 vdel.len = 0;
1483 } 1568 }
1484 1569
1485 inlen = PyByteArray_GET_SIZE(input_obj); 1570 inlen = PyByteArray_GET_SIZE(input_obj);
1486 result = PyByteArray_FromStringAndSize((char *)NULL, inlen); 1571 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1487 if (result == NULL) 1572 if (result == NULL)
1488 goto done; 1573 goto done;
1489 output_start = output = PyByteArray_AsString(result); 1574 output_start = output = PyByteArray_AsString(result);
1490 input = PyByteArray_AS_STRING(input_obj); 1575 input = PyByteArray_AS_STRING(input_obj);
1491 1576
1492 if (vdel.len == 0 && table != NULL) { 1577 if (vdel.len == 0 && table_chars != NULL) {
1493 /* If no deletions are required, use faster code */ 1578 /* If no deletions are required, use faster code */
1494 for (i = inlen; --i >= 0; ) { 1579 for (i = inlen; --i >= 0; ) {
1495 c = Py_CHARMASK(*input++); 1580 c = Py_CHARMASK(*input++);
1496 *output++ = table[c]; 1581 *output++ = table_chars[c];
1497 } 1582 }
1498 goto done; 1583 goto done;
1499 } 1584 }
1500 1585
1501 if (table == NULL) { 1586 if (table_chars == NULL) {
1502 for (i = 0; i < 256; i++) 1587 for (i = 0; i < 256; i++)
1503 trans_table[i] = Py_CHARMASK(i); 1588 trans_table[i] = Py_CHARMASK(i);
1504 } else { 1589 } else {
1505 for (i = 0; i < 256; i++) 1590 for (i = 0; i < 256; i++)
1506 trans_table[i] = Py_CHARMASK(table[i]); 1591 trans_table[i] = Py_CHARMASK(table_chars[i]);
1507 } 1592 }
1508 1593
1509 for (i = 0; i < vdel.len; i++) 1594 for (i = 0; i < vdel.len; i++)
1510 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1; 1595 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1511 1596
1512 for (i = inlen; --i >= 0; ) { 1597 for (i = inlen; --i >= 0; ) {
1513 c = Py_CHARMASK(*input++); 1598 c = Py_CHARMASK(*input++);
1514 if (trans_table[c] != -1) 1599 if (trans_table[c] != -1)
1515 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c) 1600 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1516 continue; 1601 continue;
1517 } 1602 }
1518 /* Fix the size of the resulting string */ 1603 /* Fix the size of the resulting string */
1519 if (inlen > 0) 1604 if (inlen > 0)
1520 PyByteArray_Resize(result, output - output_start); 1605 if (PyByteArray_Resize(result, output - output_start) < 0) {
1606 Py_CLEAR(result);
1607 goto done;
1608 }
1521 1609
1522 done: 1610 done:
1523 if (tableobj != NULL) 1611 if (table != NULL)
1524 PyBuffer_Release(&vtable); 1612 PyBuffer_Release(&vtable);
1525 if (delobj != NULL) 1613 if (deletechars != NULL)
1526 PyBuffer_Release(&vdel); 1614 PyBuffer_Release(&vdel);
1527 return result; 1615 return result;
1616 }
1617
1618
1619 /*[clinic input]
1620
1621 @staticmethod
1622 bytearray.maketrans
1623
1624 frm: Py_buffer
1625 to: Py_buffer
1626 /
1627
1628 Return a translation table useable for the bytes or bytearray translate method.
1629
1630 The returned table will be one where each byte in frm is mapped to the byte at
1631 the same position in to.
1632
1633 The bytes objects frm and to must be of the same length.
1634 [clinic start generated code]*/
1635
1636 static PyObject *
1637 bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
1638 /*[clinic end generated code: output=1df267d99f56b15e input=5925a81d2fbbf151]*/
1639 {
1640 return _Py_bytes_maketrans(frm, to);
1528 } 1641 }
1529 1642
1530 1643
1531 /* find and count characters and substrings */ 1644 /* find and count characters and substrings */
1532 1645
1533 #define findchar(target, target_len, c) \ 1646 #define findchar(target, target_len, c) \
1534 ((char *)memchr((const void *)(target), c, target_len)) 1647 ((char *)memchr((const void *)(target), c, target_len))
1535 1648
1536 1649
1537 /* Bytes ops must return a string, create a copy */ 1650 /* Bytes ops must return a string, create a copy */
1538 Py_LOCAL(PyByteArrayObject *) 1651 Py_LOCAL(PyByteArrayObject *)
1539 return_self(PyByteArrayObject *self) 1652 return_self(PyByteArrayObject *self)
1540 { 1653 {
1654 /* always return a new bytearray */
1541 return (PyByteArrayObject *)PyByteArray_FromStringAndSize( 1655 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1542 PyByteArray_AS_STRING(self), 1656 PyByteArray_AS_STRING(self),
1543 PyByteArray_GET_SIZE(self)); 1657 PyByteArray_GET_SIZE(self));
1544 } 1658 }
1545 1659
1546 Py_LOCAL_INLINE(Py_ssize_t) 1660 Py_LOCAL_INLINE(Py_ssize_t)
1547 countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount ) 1661 countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount )
1548 { 1662 {
1549 Py_ssize_t count=0; 1663 Py_ssize_t count=0;
1550 const char *start=target; 1664 const char *start=target;
(...skipping 12 matching lines...) Expand all
1563 /* Algorithms for different cases of string replacement */ 1677 /* Algorithms for different cases of string replacement */
1564 1678
1565 /* len(self)>=1, from="", len(to)>=1, maxcount>=1 */ 1679 /* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1566 Py_LOCAL(PyByteArrayObject *) 1680 Py_LOCAL(PyByteArrayObject *)
1567 replace_interleave(PyByteArrayObject *self, 1681 replace_interleave(PyByteArrayObject *self,
1568 const char *to_s, Py_ssize_t to_len, 1682 const char *to_s, Py_ssize_t to_len,
1569 Py_ssize_t maxcount) 1683 Py_ssize_t maxcount)
1570 { 1684 {
1571 char *self_s, *result_s; 1685 char *self_s, *result_s;
1572 Py_ssize_t self_len, result_len; 1686 Py_ssize_t self_len, result_len;
1573 Py_ssize_t count, i, product; 1687 Py_ssize_t count, i;
1574 PyByteArrayObject *result; 1688 PyByteArrayObject *result;
1575 1689
1576 self_len = PyByteArray_GET_SIZE(self); 1690 self_len = PyByteArray_GET_SIZE(self);
1577 1691
1578 /* 1 at the end plus 1 after every character */ 1692 /* 1 at the end plus 1 after every character;
1579 count = self_len+1; 1693 count = min(maxcount, self_len + 1) */
1580 if (maxcount < count) 1694 if (maxcount <= self_len)
1581 count = maxcount; 1695 count = maxcount;
1696 else
1697 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1698 count = self_len + 1;
1582 1699
1583 /* Check for overflow */ 1700 /* Check for overflow */
1584 /* result_len = count * to_len + self_len; */ 1701 /* result_len = count * to_len + self_len; */
1585 product = count * to_len; 1702 assert(count > 0);
1586 if (product / to_len != count) { 1703 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
1587 PyErr_SetString(PyExc_OverflowError, 1704 PyErr_SetString(PyExc_OverflowError,
1588 "replace string is too long"); 1705 "replace string is too long");
1589 return NULL; 1706 return NULL;
1590 } 1707 }
1591 result_len = product + self_len; 1708 result_len = count * to_len + self_len;
1592 if (result_len < 0) {
1593 PyErr_SetString(PyExc_OverflowError,
1594 "replace string is too long");
1595 return NULL;
1596 }
1597 1709
1598 if (! (result = (PyByteArrayObject *) 1710 if (! (result = (PyByteArrayObject *)
1599 PyByteArray_FromStringAndSize(NULL, result_len)) ) 1711 PyByteArray_FromStringAndSize(NULL, result_len)) )
1600 return NULL; 1712 return NULL;
1601 1713
1602 self_s = PyByteArray_AS_STRING(self); 1714 self_s = PyByteArray_AS_STRING(self);
1603 result_s = PyByteArray_AS_STRING(result); 1715 result_s = PyByteArray_AS_STRING(result);
1604 1716
1605 /* TODO: special case single character, which doesn't need memcpy */ 1717 /* TODO: special case single character, which doesn't need memcpy */
1606 1718
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 /* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */ 1928 /* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1817 Py_LOCAL(PyByteArrayObject *) 1929 Py_LOCAL(PyByteArrayObject *)
1818 replace_single_character(PyByteArrayObject *self, 1930 replace_single_character(PyByteArrayObject *self,
1819 char from_c, 1931 char from_c,
1820 const char *to_s, Py_ssize_t to_len, 1932 const char *to_s, Py_ssize_t to_len,
1821 Py_ssize_t maxcount) 1933 Py_ssize_t maxcount)
1822 { 1934 {
1823 char *self_s, *result_s; 1935 char *self_s, *result_s;
1824 char *start, *next, *end; 1936 char *start, *next, *end;
1825 Py_ssize_t self_len, result_len; 1937 Py_ssize_t self_len, result_len;
1826 Py_ssize_t count, product; 1938 Py_ssize_t count;
1827 PyByteArrayObject *result; 1939 PyByteArrayObject *result;
1828 1940
1829 self_s = PyByteArray_AS_STRING(self); 1941 self_s = PyByteArray_AS_STRING(self);
1830 self_len = PyByteArray_GET_SIZE(self); 1942 self_len = PyByteArray_GET_SIZE(self);
1831 1943
1832 count = countchar(self_s, self_len, from_c, maxcount); 1944 count = countchar(self_s, self_len, from_c, maxcount);
1833 if (count == 0) { 1945 if (count == 0) {
1834 /* no matches, return unchanged */ 1946 /* no matches, return unchanged */
1835 return return_self(self); 1947 return return_self(self);
1836 } 1948 }
1837 1949
1838 /* use the difference between current and new, hence the "-1" */ 1950 /* use the difference between current and new, hence the "-1" */
1839 /* result_len = self_len + count * (to_len-1) */ 1951 /* result_len = self_len + count * (to_len-1) */
1840 product = count * (to_len-1); 1952 assert(count > 0);
1841 if (product / (to_len-1) != count) { 1953 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
1842 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); 1954 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1843 return NULL; 1955 return NULL;
1844 } 1956 }
1845 result_len = self_len + product; 1957 result_len = self_len + count * (to_len - 1);
1846 if (result_len < 0) {
1847 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1848 return NULL;
1849 }
1850 1958
1851 if ( (result = (PyByteArrayObject *) 1959 if ( (result = (PyByteArrayObject *)
1852 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) 1960 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1853 return NULL; 1961 return NULL;
1854 result_s = PyByteArray_AS_STRING(result); 1962 result_s = PyByteArray_AS_STRING(result);
1855 1963
1856 start = self_s; 1964 start = self_s;
1857 end = self_s + self_len; 1965 end = self_s + self_len;
1858 while (count-- > 0) { 1966 while (count-- > 0) {
1859 next = findchar(start, end-start, from_c); 1967 next = findchar(start, end-start, from_c);
(...skipping 23 matching lines...) Expand all
1883 /* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */ 1991 /* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1884 Py_LOCAL(PyByteArrayObject *) 1992 Py_LOCAL(PyByteArrayObject *)
1885 replace_substring(PyByteArrayObject *self, 1993 replace_substring(PyByteArrayObject *self,
1886 const char *from_s, Py_ssize_t from_len, 1994 const char *from_s, Py_ssize_t from_len,
1887 const char *to_s, Py_ssize_t to_len, 1995 const char *to_s, Py_ssize_t to_len,
1888 Py_ssize_t maxcount) 1996 Py_ssize_t maxcount)
1889 { 1997 {
1890 char *self_s, *result_s; 1998 char *self_s, *result_s;
1891 char *start, *next, *end; 1999 char *start, *next, *end;
1892 Py_ssize_t self_len, result_len; 2000 Py_ssize_t self_len, result_len;
1893 Py_ssize_t count, offset, product; 2001 Py_ssize_t count, offset;
1894 PyByteArrayObject *result; 2002 PyByteArrayObject *result;
1895 2003
1896 self_s = PyByteArray_AS_STRING(self); 2004 self_s = PyByteArray_AS_STRING(self);
1897 self_len = PyByteArray_GET_SIZE(self); 2005 self_len = PyByteArray_GET_SIZE(self);
1898 2006
1899 count = stringlib_count(self_s, self_len, 2007 count = stringlib_count(self_s, self_len,
1900 from_s, from_len, 2008 from_s, from_len,
1901 maxcount); 2009 maxcount);
1902 2010
1903 if (count == 0) { 2011 if (count == 0) {
1904 /* no matches, return unchanged */ 2012 /* no matches, return unchanged */
1905 return return_self(self); 2013 return return_self(self);
1906 } 2014 }
1907 2015
1908 /* Check for overflow */ 2016 /* Check for overflow */
1909 /* result_len = self_len + count * (to_len-from_len) */ 2017 /* result_len = self_len + count * (to_len-from_len) */
1910 product = count * (to_len-from_len); 2018 assert(count > 0);
1911 if (product / (to_len-from_len) != count) { 2019 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
1912 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); 2020 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1913 return NULL; 2021 return NULL;
1914 } 2022 }
1915 result_len = self_len + product; 2023 result_len = self_len + count * (to_len - from_len);
1916 if (result_len < 0) {
1917 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1918 return NULL;
1919 }
1920 2024
1921 if ( (result = (PyByteArrayObject *) 2025 if ( (result = (PyByteArrayObject *)
1922 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) 2026 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1923 return NULL; 2027 return NULL;
1924 result_s = PyByteArray_AS_STRING(result); 2028 result_s = PyByteArray_AS_STRING(result);
1925 2029
1926 start = self_s; 2030 start = self_s;
1927 end = self_s + self_len; 2031 end = self_s + self_len;
1928 while (count-- > 0) { 2032 while (count-- > 0) {
1929 offset = stringlib_find(start, end-start, 2033 offset = stringlib_find(start, end-start,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1982 } 2086 }
1983 2087
1984 /* Except for "".replace("", "A") == "A" there is no way beyond this */ 2088 /* Except for "".replace("", "A") == "A" there is no way beyond this */
1985 /* point for an empty self bytes to generate a non-empty bytes */ 2089 /* point for an empty self bytes to generate a non-empty bytes */
1986 /* Special case so the remaining code always gets a non-empty bytes */ 2090 /* Special case so the remaining code always gets a non-empty bytes */
1987 if (PyByteArray_GET_SIZE(self) == 0) { 2091 if (PyByteArray_GET_SIZE(self) == 0) {
1988 return return_self(self); 2092 return return_self(self);
1989 } 2093 }
1990 2094
1991 if (to_len == 0) { 2095 if (to_len == 0) {
1992 /* delete all occurances of 'from' bytes */ 2096 /* delete all occurrences of 'from' bytes */
1993 if (from_len == 1) { 2097 if (from_len == 1) {
1994 return replace_delete_single_character( 2098 return replace_delete_single_character(
1995 self, from_s[0], maxcount); 2099 self, from_s[0], maxcount);
1996 } else { 2100 } else {
1997 return replace_delete_substring(self, from_s, from_len, maxcount); 2101 return replace_delete_substring(self, from_s, from_len, maxcount);
1998 } 2102 }
1999 } 2103 }
2000 2104
2001 /* Handle special case where both bytes have the same length */ 2105 /* Handle special case where both bytes have the same length */
2002 2106
(...skipping 14 matching lines...) Expand all
2017 if (from_len == 1) { 2121 if (from_len == 1) {
2018 return replace_single_character(self, from_s[0], 2122 return replace_single_character(self, from_s[0],
2019 to_s, to_len, maxcount); 2123 to_s, to_len, maxcount);
2020 } else { 2124 } else {
2021 /* len('from')>=2, len('to')>=1 */ 2125 /* len('from')>=2, len('to')>=1 */
2022 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount) ; 2126 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount) ;
2023 } 2127 }
2024 } 2128 }
2025 2129
2026 2130
2027 PyDoc_STRVAR(replace__doc__, 2131 /*[clinic input]
2028 "B.replace(old, new[, count]) -> bytes\n\ 2132 bytearray.replace
2029 \n\ 2133
2030 Return a copy of B with all occurrences of subsection\n\ 2134 old: Py_buffer
2031 old replaced by new. If the optional argument count is\n\ 2135 new: Py_buffer
2032 given, only the first count occurrences are replaced."); 2136 count: Py_ssize_t = -1
2033 2137 Maximum number of occurrences to replace.
2034 static PyObject * 2138 -1 (the default value) means replace all occurrences.
2035 bytearray_replace(PyByteArrayObject *self, PyObject *args) 2139 /
2036 { 2140
2037 Py_ssize_t count = -1; 2141 Return a copy with all occurrences of substring old replaced by new.
2038 PyObject *from, *to, *res; 2142
2039 Py_buffer vfrom, vto; 2143 If the optional argument count is given, only the first count occurrences are
2040 2144 replaced.
2041 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) 2145 [clinic start generated code]*/
2042 return NULL; 2146
2043 2147 static PyObject *
2044 if (_getbuffer(from, &vfrom) < 0) 2148 bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old,
2045 return NULL; 2149 Py_buffer *new, Py_ssize_t count)
2046 if (_getbuffer(to, &vto) < 0) { 2150 /*[clinic end generated code: output=d39884c4dc59412a input=aa379d988637c7fb]*/
2047 PyBuffer_Release(&vfrom); 2151 {
2048 return NULL; 2152 return (PyObject *)replace((PyByteArrayObject *) self,
2049 } 2153 old->buf, old->len,
2050 2154 new->buf, new->len, count);
2051 res = (PyObject *)replace((PyByteArrayObject *) self, 2155 }
2052 vfrom.buf, vfrom.len, 2156
2053 vto.buf, vto.len, count); 2157 /*[clinic input]
2054 2158 bytearray.split
2055 PyBuffer_Release(&vfrom); 2159
2056 PyBuffer_Release(&vto); 2160 sep: object = None
2057 return res; 2161 The delimiter according which to split the bytearray.
2058 } 2162 None (the default value) means split on ASCII whitespace characters
2059 2163 (space, tab, return, newline, formfeed, vertical tab).
2060 PyDoc_STRVAR(split__doc__, 2164 maxsplit: Py_ssize_t = -1
2061 "B.split([sep[, maxsplit]]) -> list of bytearray\n\ 2165 Maximum number of splits to do.
2062 \n\ 2166 -1 (the default value) means no limit.
2063 Return a list of the sections in B, using sep as the delimiter.\n\ 2167
2064 If sep is not given, B is split on ASCII whitespace characters\n\ 2168 Return a list of the sections in the bytearray, using sep as the delimiter.
2065 (space, tab, return, newline, formfeed, vertical tab).\n\ 2169 [clinic start generated code]*/
2066 If maxsplit is given, at most maxsplit splits are done."); 2170
2067 2171 static PyObject *
2068 static PyObject * 2172 bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
2069 bytearray_split(PyByteArrayObject *self, PyObject *args) 2173 Py_ssize_t maxsplit)
2174 /*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/
2070 { 2175 {
2071 Py_ssize_t len = PyByteArray_GET_SIZE(self), n; 2176 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2072 Py_ssize_t maxsplit = -1;
2073 const char *s = PyByteArray_AS_STRING(self), *sub; 2177 const char *s = PyByteArray_AS_STRING(self), *sub;
2074 PyObject *list, *subobj = Py_None; 2178 PyObject *list;
2075 Py_buffer vsub; 2179 Py_buffer vsub;
2076 2180
2077 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2078 return NULL;
2079 if (maxsplit < 0) 2181 if (maxsplit < 0)
2080 maxsplit = PY_SSIZE_T_MAX; 2182 maxsplit = PY_SSIZE_T_MAX;
2081 2183
2082 if (subobj == Py_None) 2184 if (sep == Py_None)
2083 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); 2185 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
2084 2186
2085 if (_getbuffer(subobj, &vsub) < 0) 2187 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
2086 return NULL; 2188 return NULL;
2087 sub = vsub.buf; 2189 sub = vsub.buf;
2088 n = vsub.len; 2190 n = vsub.len;
2089 2191
2090 list = stringlib_split( 2192 list = stringlib_split(
2091 (PyObject*) self, s, len, sub, n, maxsplit 2193 (PyObject*) self, s, len, sub, n, maxsplit
2092 ); 2194 );
2093 PyBuffer_Release(&vsub); 2195 PyBuffer_Release(&vsub);
2094 return list; 2196 return list;
2095 } 2197 }
2096 2198
2097 PyDoc_STRVAR(partition__doc__, 2199 /*[clinic input]
2098 "B.partition(sep) -> (head, sep, tail)\n\ 2200 bytearray.partition
2099 \n\ 2201
2100 Searches for the separator sep in B, and returns the part before it,\n\ 2202 self: self(type="PyByteArrayObject *")
2101 the separator itself, and the part after it. If the separator is not\n\ 2203 sep: object
2102 found, returns B and two empty bytearray objects."); 2204 /
2103 2205
2104 static PyObject * 2206 Partition the bytearray into three parts using the given separator.
2105 bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) 2207
2208 This will search for the separator sep in the bytearray. If the separator is
2209 found, returns a 3-tuple containing the part before the separator, the
2210 separator itself, and the part after it.
2211
2212 If the separator is not found, returns a 3-tuple containing the original
2213 bytearray object and two empty bytearray objects.
2214 [clinic start generated code]*/
2215
2216 static PyObject *
2217 bytearray_partition(PyByteArrayObject *self, PyObject *sep)
2218 /*[clinic end generated code: output=45d2525ddd35f957 input=7d7fe37b1696d506]*/
2106 { 2219 {
2107 PyObject *bytesep, *result; 2220 PyObject *bytesep, *result;
2108 2221
2109 bytesep = PyByteArray_FromObject(sep_obj); 2222 bytesep = PyByteArray_FromObject(sep);
2110 if (! bytesep) 2223 if (! bytesep)
2111 return NULL; 2224 return NULL;
2112 2225
2113 result = stringlib_partition( 2226 result = stringlib_partition(
2114 (PyObject*) self, 2227 (PyObject*) self,
2115 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), 2228 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2116 bytesep, 2229 bytesep,
2117 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep) 2230 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2118 ); 2231 );
2119 2232
2120 Py_DECREF(bytesep); 2233 Py_DECREF(bytesep);
2121 return result; 2234 return result;
2122 } 2235 }
2123 2236
2124 PyDoc_STRVAR(rpartition__doc__, 2237 /*[clinic input]
2125 "B.rpartition(sep) -> (head, sep, tail)\n\ 2238 bytearray.rpartition
2126 \n\ 2239
2127 Searches for the separator sep in B, starting at the end of B,\n\ 2240 self: self(type="PyByteArrayObject *")
2128 and returns the part before it, the separator itself, and the\n\ 2241 sep: object
2129 part after it. If the separator is not found, returns two empty\n\ 2242 /
2130 bytearray objects and B."); 2243
2131 2244 Partition the bytes into three parts using the given separator.
2132 static PyObject * 2245
2133 bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj) 2246 This will search for the separator sep in the bytearray, starting and the end.
2247 If the separator is found, returns a 3-tuple containing the part before the
2248 separator, the separator itself, and the part after it.
2249
2250 If the separator is not found, returns a 3-tuple containing two empty bytearray
2251 objects and the original bytearray object.
2252 [clinic start generated code]*/
2253
2254 static PyObject *
2255 bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
2256 /*[clinic end generated code: output=440de3c9426115e8 input=9b8cd540c1b75853]*/
2134 { 2257 {
2135 PyObject *bytesep, *result; 2258 PyObject *bytesep, *result;
2136 2259
2137 bytesep = PyByteArray_FromObject(sep_obj); 2260 bytesep = PyByteArray_FromObject(sep);
2138 if (! bytesep) 2261 if (! bytesep)
2139 return NULL; 2262 return NULL;
2140 2263
2141 result = stringlib_rpartition( 2264 result = stringlib_rpartition(
2142 (PyObject*) self, 2265 (PyObject*) self,
2143 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), 2266 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2144 bytesep, 2267 bytesep,
2145 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep) 2268 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2146 ); 2269 );
2147 2270
2148 Py_DECREF(bytesep); 2271 Py_DECREF(bytesep);
2149 return result; 2272 return result;
2150 } 2273 }
2151 2274
2152 PyDoc_STRVAR(rsplit__doc__, 2275 /*[clinic input]
2153 "B.rsplit(sep[, maxsplit]) -> list of bytearray\n\ 2276 bytearray.rsplit = bytearray.split
2154 \n\ 2277
2155 Return a list of the sections in B, using sep as the delimiter,\n\ 2278 Return a list of the sections in the bytearray, using sep as the delimiter.
2156 starting at the end of B and working to the front.\n\ 2279
2157 If sep is not given, B is split on ASCII whitespace characters\n\ 2280 Splitting is done starting at the end of the bytearray and working to the front.
2158 (space, tab, return, newline, formfeed, vertical tab).\n\ 2281 [clinic start generated code]*/
2159 If maxsplit is given, at most maxsplit splits are done."); 2282
2160 2283 static PyObject *
2161 static PyObject * 2284 bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
2162 bytearray_rsplit(PyByteArrayObject *self, PyObject *args) 2285 Py_ssize_t maxsplit)
2286 /*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/
2163 { 2287 {
2164 Py_ssize_t len = PyByteArray_GET_SIZE(self), n; 2288 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2165 Py_ssize_t maxsplit = -1;
2166 const char *s = PyByteArray_AS_STRING(self), *sub; 2289 const char *s = PyByteArray_AS_STRING(self), *sub;
2167 PyObject *list, *subobj = Py_None; 2290 PyObject *list;
2168 Py_buffer vsub; 2291 Py_buffer vsub;
2169 2292
2170 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2171 return NULL;
2172 if (maxsplit < 0) 2293 if (maxsplit < 0)
2173 maxsplit = PY_SSIZE_T_MAX; 2294 maxsplit = PY_SSIZE_T_MAX;
2174 2295
2175 if (subobj == Py_None) 2296 if (sep == Py_None)
2176 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); 2297 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
2177 2298
2178 if (_getbuffer(subobj, &vsub) < 0) 2299 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
2179 return NULL; 2300 return NULL;
2180 sub = vsub.buf; 2301 sub = vsub.buf;
2181 n = vsub.len; 2302 n = vsub.len;
2182 2303
2183 list = stringlib_rsplit( 2304 list = stringlib_rsplit(
2184 (PyObject*) self, s, len, sub, n, maxsplit 2305 (PyObject*) self, s, len, sub, n, maxsplit
2185 ); 2306 );
2186 PyBuffer_Release(&vsub); 2307 PyBuffer_Release(&vsub);
2187 return list; 2308 return list;
2188 } 2309 }
2189 2310
2190 PyDoc_STRVAR(reverse__doc__, 2311 /*[clinic input]
2191 "B.reverse() -> None\n\ 2312 bytearray.reverse
2192 \n\ 2313
2193 Reverse the order of the values in B in place."); 2314 self: self(type="PyByteArrayObject *")
2194 static PyObject * 2315
2195 bytearray_reverse(PyByteArrayObject *self, PyObject *unused) 2316 Reverse the order of the values in B in place.
2317 [clinic start generated code]*/
2318
2319 static PyObject *
2320 bytearray_reverse_impl(PyByteArrayObject *self)
2321 /*[clinic end generated code: output=9f7616f29ab309d3 input=7933a499b8597bd1]*/
2196 { 2322 {
2197 char swap, *head, *tail; 2323 char swap, *head, *tail;
2198 Py_ssize_t i, j, n = Py_SIZE(self); 2324 Py_ssize_t i, j, n = Py_SIZE(self);
2199 2325
2200 j = n / 2; 2326 j = n / 2;
2201 head = self->ob_bytes; 2327 head = PyByteArray_AS_STRING(self);
2202 tail = head + n - 1; 2328 tail = head + n - 1;
2203 for (i = 0; i < j; i++) { 2329 for (i = 0; i < j; i++) {
2204 swap = *head; 2330 swap = *head;
2205 *head++ = *tail; 2331 *head++ = *tail;
2206 *tail-- = swap; 2332 *tail-- = swap;
2207 } 2333 }
2208 2334
2209 Py_RETURN_NONE; 2335 Py_RETURN_NONE;
2210 } 2336 }
2211 2337
2212 PyDoc_STRVAR(insert__doc__, 2338
2213 "B.insert(index, int) -> None\n\ 2339 /*[python input]
2214 \n\ 2340 class bytesvalue_converter(CConverter):
2215 Insert a single item into the bytearray before the given index."); 2341 type = 'int'
2216 static PyObject * 2342 converter = '_getbytevalue'
2217 bytearray_insert(PyByteArrayObject *self, PyObject *args) 2343 [python start generated code]*/
2218 { 2344 /*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
2219 PyObject *value; 2345
2220 int ival; 2346
2221 Py_ssize_t where, n = Py_SIZE(self); 2347 /*[clinic input]
2222 2348 bytearray.insert
2223 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value)) 2349
2224 return NULL; 2350 self: self(type="PyByteArrayObject *")
2351 index: Py_ssize_t
2352 The index where the value is to be inserted.
2353 item: bytesvalue
2354 The item to be inserted.
2355 /
2356
2357 Insert a single item into the bytearray before the given index.
2358 [clinic start generated code]*/
2359
2360 static PyObject *
2361 bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
2362 /*[clinic end generated code: output=76c775a70e7b07b7 input=833766836ba30e1e]*/
2363 {
2364 Py_ssize_t n = Py_SIZE(self);
2365 char *buf;
2225 2366
2226 if (n == PY_SSIZE_T_MAX) { 2367 if (n == PY_SSIZE_T_MAX) {
2227 PyErr_SetString(PyExc_OverflowError, 2368 PyErr_SetString(PyExc_OverflowError,
2228 "cannot add more objects to bytearray"); 2369 "cannot add more objects to bytearray");
2229 return NULL; 2370 return NULL;
2230 } 2371 }
2231 if (!_getbytevalue(value, &ival))
2232 return NULL;
2233 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) 2372 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2234 return NULL; 2373 return NULL;
2235 2374 buf = PyByteArray_AS_STRING(self);
2236 if (where < 0) { 2375
2237 where += n; 2376 if (index < 0) {
2238 if (where < 0) 2377 index += n;
2239 where = 0; 2378 if (index < 0)
2240 } 2379 index = 0;
2241 if (where > n) 2380 }
2242 where = n; 2381 if (index > n)
2243 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where); 2382 index = n;
2244 self->ob_bytes[where] = ival; 2383 memmove(buf + index + 1, buf + index, n - index);
2384 buf[index] = item;
2245 2385
2246 Py_RETURN_NONE; 2386 Py_RETURN_NONE;
2247 } 2387 }
2248 2388
2249 PyDoc_STRVAR(append__doc__, 2389 /*[clinic input]
2250 "B.append(int) -> None\n\ 2390 bytearray.append
2251 \n\ 2391
2252 Append a single item to the end of B."); 2392 self: self(type="PyByteArrayObject *")
2253 static PyObject * 2393 item: bytesvalue
2254 bytearray_append(PyByteArrayObject *self, PyObject *arg) 2394 The item to be appended.
2255 { 2395 /
2256 int value; 2396
2397 Append a single item to the end of the bytearray.
2398 [clinic start generated code]*/
2399
2400 static PyObject *
2401 bytearray_append_impl(PyByteArrayObject *self, int item)
2402 /*[clinic end generated code: output=a154e19ed1886cb6 input=ae56ea87380407cc]*/
2403 {
2257 Py_ssize_t n = Py_SIZE(self); 2404 Py_ssize_t n = Py_SIZE(self);
2258 2405
2259 if (! _getbytevalue(arg, &value))
2260 return NULL;
2261 if (n == PY_SSIZE_T_MAX) { 2406 if (n == PY_SSIZE_T_MAX) {
2262 PyErr_SetString(PyExc_OverflowError, 2407 PyErr_SetString(PyExc_OverflowError,
2263 "cannot add more objects to bytearray"); 2408 "cannot add more objects to bytearray");
2264 return NULL; 2409 return NULL;
2265 } 2410 }
2266 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) 2411 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2267 return NULL; 2412 return NULL;
2268 2413
2269 self->ob_bytes[n] = value; 2414 PyByteArray_AS_STRING(self)[n] = item;
2270 2415
2271 Py_RETURN_NONE; 2416 Py_RETURN_NONE;
2272 } 2417 }
2273 2418
2274 PyDoc_STRVAR(extend__doc__, 2419 /*[clinic input]
2275 "B.extend(iterable int) -> None\n\ 2420 bytearray.extend
2276 \n\ 2421
2277 Append all the elements from the iterator or sequence to the\n\ 2422 self: self(type="PyByteArrayObject *")
2278 end of B."); 2423 iterable_of_ints: object
2279 static PyObject * 2424 The iterable of items to append.
2280 bytearray_extend(PyByteArrayObject *self, PyObject *arg) 2425 /
2426
2427 Append all the items from the iterator or sequence to the end of the bytearray.
2428 [clinic start generated code]*/
2429
2430 static PyObject *
2431 bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
2432 /*[clinic end generated code: output=98155dbe249170b1 input=ce83a5d75b70d850]*/
2281 { 2433 {
2282 PyObject *it, *item, *bytearray_obj; 2434 PyObject *it, *item, *bytearray_obj;
2283 Py_ssize_t buf_size = 0, len = 0; 2435 Py_ssize_t buf_size = 0, len = 0;
2284 int value; 2436 int value;
2285 char *buf; 2437 char *buf;
2286 2438
2287 /* bytearray_setslice code only accepts something supporting PEP 3118. */ 2439 /* bytearray_setslice code only accepts something supporting PEP 3118. */
2288 if (PyObject_CheckBuffer(arg)) { 2440 if (PyObject_CheckBuffer(iterable_of_ints)) {
2289 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) 2441 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_i nts) == -1)
2290 return NULL; 2442 return NULL;
2291 2443
2292 Py_RETURN_NONE; 2444 Py_RETURN_NONE;
2293 } 2445 }
2294 2446
2295 it = PyObject_GetIter(arg); 2447 it = PyObject_GetIter(iterable_of_ints);
2296 if (it == NULL) 2448 if (it == NULL)
2297 return NULL; 2449 return NULL;
2298 2450
2299 /* Try to determine the length of the argument. 32 is arbitrary. */ 2451 /* Try to determine the length of the argument. 32 is arbitrary. */
2300 buf_size = _PyObject_LengthHint(arg, 32); 2452 buf_size = PyObject_LengthHint(iterable_of_ints, 32);
2301 if (buf_size == -1) { 2453 if (buf_size == -1) {
2302 Py_DECREF(it); 2454 Py_DECREF(it);
2303 return NULL; 2455 return NULL;
2304 } 2456 }
2305 2457
2306 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size); 2458 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2307 if (bytearray_obj == NULL) { 2459 if (bytearray_obj == NULL) {
2308 Py_DECREF(it); 2460 Py_DECREF(it);
2309 return NULL; 2461 return NULL;
2310 } 2462 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2342 2494
2343 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) { 2495 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2344 Py_DECREF(bytearray_obj); 2496 Py_DECREF(bytearray_obj);
2345 return NULL; 2497 return NULL;
2346 } 2498 }
2347 Py_DECREF(bytearray_obj); 2499 Py_DECREF(bytearray_obj);
2348 2500
2349 Py_RETURN_NONE; 2501 Py_RETURN_NONE;
2350 } 2502 }
2351 2503
2352 PyDoc_STRVAR(pop__doc__, 2504 /*[clinic input]
2353 "B.pop([index]) -> int\n\ 2505 bytearray.pop
2354 \n\ 2506
2355 Remove and return a single item from B. If no index\n\ 2507 self: self(type="PyByteArrayObject *")
2356 argument is given, will pop the last value."); 2508 index: Py_ssize_t = -1
2357 static PyObject * 2509 The index from where to remove the item.
2358 bytearray_pop(PyByteArrayObject *self, PyObject *args) 2510 -1 (the default value) means remove the last item.
2511 /
2512
2513 Remove and return a single item from B.
2514
2515 If no index argument is given, will pop the last item.
2516 [clinic start generated code]*/
2517
2518 static PyObject *
2519 bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
2520 /*[clinic end generated code: output=e0ccd401f8021da8 input=0797e6c0ca9d5a85]*/
2359 { 2521 {
2360 int value; 2522 int value;
2361 Py_ssize_t where = -1, n = Py_SIZE(self); 2523 Py_ssize_t n = Py_SIZE(self);
2362 2524 char *buf;
2363 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2364 return NULL;
2365 2525
2366 if (n == 0) { 2526 if (n == 0) {
2367 PyErr_SetString(PyExc_IndexError, 2527 PyErr_SetString(PyExc_IndexError,
2368 "pop from empty bytearray"); 2528 "pop from empty bytearray");
2369 return NULL; 2529 return NULL;
2370 } 2530 }
2371 if (where < 0) 2531 if (index < 0)
2372 where += n; 2532 index += Py_SIZE(self);
2373 if (where < 0 || where >= n) { 2533 if (index < 0 || index >= Py_SIZE(self)) {
2374 PyErr_SetString(PyExc_IndexError, "pop index out of range"); 2534 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2375 return NULL; 2535 return NULL;
2376 } 2536 }
2377 if (!_canresize(self)) 2537 if (!_canresize(self))
2378 return NULL; 2538 return NULL;
2379 2539
2380 value = self->ob_bytes[where]; 2540 buf = PyByteArray_AS_STRING(self);
2381 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where - 1); 2541 value = buf[index];
2542 memmove(buf + index, buf + index + 1, n - index);
2382 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) 2543 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2383 return NULL; 2544 return NULL;
2384 2545
2385 return PyInt_FromLong((unsigned char)value); 2546 return PyLong_FromLong((unsigned char)value);
2386 } 2547 }
2387 2548
2388 PyDoc_STRVAR(remove__doc__, 2549 /*[clinic input]
2389 "B.remove(int) -> None\n\ 2550 bytearray.remove
2390 \n\ 2551
2391 Remove the first occurance of a value in B."); 2552 self: self(type="PyByteArrayObject *")
2392 static PyObject * 2553 value: bytesvalue
2393 bytearray_remove(PyByteArrayObject *self, PyObject *arg) 2554 The value to remove.
2394 { 2555 /
2395 int value; 2556
2557 Remove the first occurrence of a value in the bytearray.
2558 [clinic start generated code]*/
2559
2560 static PyObject *
2561 bytearray_remove_impl(PyByteArrayObject *self, int value)
2562 /*[clinic end generated code: output=d659e37866709c13 input=47560b11fd856c24]*/
2563 {
2396 Py_ssize_t where, n = Py_SIZE(self); 2564 Py_ssize_t where, n = Py_SIZE(self);
2397 2565 char *buf = PyByteArray_AS_STRING(self);
2398 if (! _getbytevalue(arg, &value))
2399 return NULL;
2400 2566
2401 for (where = 0; where < n; where++) { 2567 for (where = 0; where < n; where++) {
2402 if (self->ob_bytes[where] == value) 2568 if (buf[where] == value)
2403 break; 2569 break;
2404 } 2570 }
2405 if (where == n) { 2571 if (where == n) {
2406 PyErr_SetString(PyExc_ValueError, "value not found in bytearray"); 2572 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
2407 return NULL; 2573 return NULL;
2408 } 2574 }
2409 if (!_canresize(self)) 2575 if (!_canresize(self))
2410 return NULL; 2576 return NULL;
2411 2577
2412 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where - 1); 2578 memmove(buf + where, buf + where + 1, n - where);
2413 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) 2579 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2414 return NULL; 2580 return NULL;
2415 2581
2416 Py_RETURN_NONE; 2582 Py_RETURN_NONE;
2417 } 2583 }
2418 2584
2419 /* XXX These two helpers could be optimized if argsize == 1 */ 2585 /* XXX These two helpers could be optimized if argsize == 1 */
2420 2586
2421 static Py_ssize_t 2587 static Py_ssize_t
2422 lstrip_helper(unsigned char *myptr, Py_ssize_t mysize, 2588 lstrip_helper(char *myptr, Py_ssize_t mysize,
2423 void *argptr, Py_ssize_t argsize) 2589 void *argptr, Py_ssize_t argsize)
2424 { 2590 {
2425 Py_ssize_t i = 0; 2591 Py_ssize_t i = 0;
2426 while (i < mysize && memchr(argptr, myptr[i], argsize)) 2592 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
2427 i++; 2593 i++;
2428 return i; 2594 return i;
2429 } 2595 }
2430 2596
2431 static Py_ssize_t 2597 static Py_ssize_t
2432 rstrip_helper(unsigned char *myptr, Py_ssize_t mysize, 2598 rstrip_helper(char *myptr, Py_ssize_t mysize,
2433 void *argptr, Py_ssize_t argsize) 2599 void *argptr, Py_ssize_t argsize)
2434 { 2600 {
2435 Py_ssize_t i = mysize - 1; 2601 Py_ssize_t i = mysize - 1;
2436 while (i >= 0 && memchr(argptr, myptr[i], argsize)) 2602 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
2437 i--; 2603 i--;
2438 return i + 1; 2604 return i + 1;
2439 } 2605 }
2440 2606
2441 PyDoc_STRVAR(strip__doc__, 2607 /*[clinic input]
2442 "B.strip([bytes]) -> bytearray\n\ 2608 bytearray.strip
2443 \n\ 2609
2444 Strip leading and trailing bytes contained in the argument.\n\ 2610 bytes: object = None
2445 If the argument is omitted, strip ASCII whitespace."); 2611 /
2446 static PyObject * 2612
2447 bytearray_strip(PyByteArrayObject *self, PyObject *args) 2613 Strip leading and trailing bytes contained in the argument.
2448 { 2614
2449 Py_ssize_t left, right, mysize, argsize; 2615 If the argument is omitted or None, strip leading and trailing ASCII whitespace.
2450 void *myptr, *argptr; 2616 [clinic start generated code]*/
2451 PyObject *arg = Py_None; 2617
2452 Py_buffer varg; 2618 static PyObject *
2453 if (!PyArg_ParseTuple(args, "|O:strip", &arg)) 2619 bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
2454 return NULL; 2620 /*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/
2455 if (arg == Py_None) { 2621 {
2456 argptr = "\t\n\r\f\v "; 2622 Py_ssize_t left, right, mysize, byteslen;
2457 argsize = 6; 2623 char *myptr, *bytesptr;
2624 Py_buffer vbytes;
2625
2626 if (bytes == Py_None) {
2627 bytesptr = "\t\n\r\f\v ";
2628 byteslen = 6;
2458 } 2629 }
2459 else { 2630 else {
2460 if (_getbuffer(arg, &varg) < 0) 2631 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
2461 return NULL; 2632 return NULL;
2462 argptr = varg.buf; 2633 bytesptr = (char *) vbytes.buf;
2463 argsize = varg.len; 2634 byteslen = vbytes.len;
2464 } 2635 }
2465 myptr = self->ob_bytes; 2636 myptr = PyByteArray_AS_STRING(self);
2466 mysize = Py_SIZE(self); 2637 mysize = Py_SIZE(self);
2467 left = lstrip_helper(myptr, mysize, argptr, argsize); 2638 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
2468 if (left == mysize) 2639 if (left == mysize)
2469 right = left; 2640 right = left;
2470 else 2641 else
2471 right = rstrip_helper(myptr, mysize, argptr, argsize); 2642 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
2472 if (arg != Py_None) 2643 if (bytes != Py_None)
2473 PyBuffer_Release(&varg); 2644 PyBuffer_Release(&vbytes);
2474 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); 2645 return PyByteArray_FromStringAndSize(myptr + left, right - left);
2475 } 2646 }
2476 2647
2477 PyDoc_STRVAR(lstrip__doc__, 2648 /*[clinic input]
2478 "B.lstrip([bytes]) -> bytearray\n\ 2649 bytearray.lstrip
2479 \n\ 2650
2480 Strip leading bytes contained in the argument.\n\ 2651 bytes: object = None
2481 If the argument is omitted, strip leading ASCII whitespace."); 2652 /
2482 static PyObject * 2653
2483 bytearray_lstrip(PyByteArrayObject *self, PyObject *args) 2654 Strip leading bytes contained in the argument.
2484 { 2655
2485 Py_ssize_t left, right, mysize, argsize; 2656 If the argument is omitted or None, strip leading ASCII whitespace.
2486 void *myptr, *argptr; 2657 [clinic start generated code]*/
2487 PyObject *arg = Py_None; 2658
2488 Py_buffer varg; 2659 static PyObject *
2489 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg)) 2660 bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
2490 return NULL; 2661 /*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/
2491 if (arg == Py_None) { 2662 {
2492 argptr = "\t\n\r\f\v "; 2663 Py_ssize_t left, right, mysize, byteslen;
2493 argsize = 6; 2664 char *myptr, *bytesptr;
2665 Py_buffer vbytes;
2666
2667 if (bytes == Py_None) {
2668 bytesptr = "\t\n\r\f\v ";
2669 byteslen = 6;
2494 } 2670 }
2495 else { 2671 else {
2496 if (_getbuffer(arg, &varg) < 0) 2672 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
2497 return NULL; 2673 return NULL;
2498 argptr = varg.buf; 2674 bytesptr = (char *) vbytes.buf;
2499 argsize = varg.len; 2675 byteslen = vbytes.len;
2500 } 2676 }
2501 myptr = self->ob_bytes; 2677 myptr = PyByteArray_AS_STRING(self);
2502 mysize = Py_SIZE(self); 2678 mysize = Py_SIZE(self);
2503 left = lstrip_helper(myptr, mysize, argptr, argsize); 2679 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
2504 right = mysize; 2680 right = mysize;
2505 if (arg != Py_None) 2681 if (bytes != Py_None)
2506 PyBuffer_Release(&varg); 2682 PyBuffer_Release(&vbytes);
2507 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); 2683 return PyByteArray_FromStringAndSize(myptr + left, right - left);
2508 } 2684 }
2509 2685
2510 PyDoc_STRVAR(rstrip__doc__, 2686 /*[clinic input]
2511 "B.rstrip([bytes]) -> bytearray\n\ 2687 bytearray.rstrip
2512 \n\ 2688
2513 Strip trailing bytes contained in the argument.\n\ 2689 bytes: object = None
2514 If the argument is omitted, strip trailing ASCII whitespace."); 2690 /
2515 static PyObject * 2691
2516 bytearray_rstrip(PyByteArrayObject *self, PyObject *args) 2692 Strip trailing bytes contained in the argument.
2517 { 2693
2518 Py_ssize_t left, right, mysize, argsize; 2694 If the argument is omitted or None, strip trailing ASCII whitespace.
2519 void *myptr, *argptr; 2695 [clinic start generated code]*/
2520 PyObject *arg = Py_None; 2696
2521 Py_buffer varg; 2697 static PyObject *
2522 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg)) 2698 bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
2523 return NULL; 2699 /*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/
2524 if (arg == Py_None) { 2700 {
2525 argptr = "\t\n\r\f\v "; 2701 Py_ssize_t right, mysize, byteslen;
2526 argsize = 6; 2702 char *myptr, *bytesptr;
2703 Py_buffer vbytes;
2704
2705 if (bytes == Py_None) {
2706 bytesptr = "\t\n\r\f\v ";
2707 byteslen = 6;
2527 } 2708 }
2528 else { 2709 else {
2529 if (_getbuffer(arg, &varg) < 0) 2710 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
2530 return NULL; 2711 return NULL;
2531 argptr = varg.buf; 2712 bytesptr = (char *) vbytes.buf;
2532 argsize = varg.len; 2713 byteslen = vbytes.len;
2533 } 2714 }
2534 myptr = self->ob_bytes; 2715 myptr = PyByteArray_AS_STRING(self);
2535 mysize = Py_SIZE(self); 2716 mysize = Py_SIZE(self);
2536 left = 0; 2717 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
2537 right = rstrip_helper(myptr, mysize, argptr, argsize); 2718 if (bytes != Py_None)
2538 if (arg != Py_None) 2719 PyBuffer_Release(&vbytes);
2539 PyBuffer_Release(&varg); 2720 return PyByteArray_FromStringAndSize(myptr, right);
2540 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); 2721 }
2541 } 2722
2542 2723 /*[clinic input]
2543 PyDoc_STRVAR(decode_doc, 2724 bytearray.decode
2544 "B.decode([encoding[, errors]]) -> unicode object.\n\ 2725
2545 \n\ 2726 encoding: str(c_default="NULL") = 'utf-8'
2546 Decodes B using the codec registered for encoding. encoding defaults\n\ 2727 The encoding with which to decode the bytearray.
2547 to the default encoding. errors may be given to set a different error\n\ 2728 errors: str(c_default="NULL") = 'strict'
2548 handling scheme. Default is 'strict' meaning that encoding errors raise\n\ 2729 The error handling scheme to use for the handling of decoding errors.
2549 a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\ 2730 The default is 'strict' meaning that decoding errors raise a
2550 as well as any other name registered with codecs.register_error that is\n\ 2731 UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
2551 able to handle UnicodeDecodeErrors."); 2732 as well as any other name registered with codecs.register_error that
2552 2733 can handle UnicodeDecodeErrors.
2553 static PyObject * 2734
2554 bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs) 2735 Decode the bytearray using the codec registered for encoding.
2555 { 2736 [clinic start generated code]*/
2556 const char *encoding = NULL; 2737
2557 const char *errors = NULL; 2738 static PyObject *
2558 static char *kwlist[] = {"encoding", "errors", 0}; 2739 bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
2559 2740 const char *errors)
2560 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encodi ng, &errors)) 2741 /*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/
2561 return NULL; 2742 {
2562 if (encoding == NULL) { 2743 if (encoding == NULL)
2563 #ifdef Py_USING_UNICODE
2564 encoding = PyUnicode_GetDefaultEncoding(); 2744 encoding = PyUnicode_GetDefaultEncoding();
2565 #else 2745 return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
2566 PyErr_SetString(PyExc_ValueError, "no encoding specified");
2567 return NULL;
2568 #endif
2569 }
2570 return _PyCodec_DecodeText(self, encoding, errors);
2571 } 2746 }
2572 2747
2573 PyDoc_STRVAR(alloc_doc, 2748 PyDoc_STRVAR(alloc_doc,
2574 "B.__alloc__() -> int\n\ 2749 "B.__alloc__() -> int\n\
2575 \n\ 2750 \n\
2576 Returns the number of bytes actually allocated."); 2751 Return the number of bytes actually allocated.");
2577 2752
2578 static PyObject * 2753 static PyObject *
2579 bytearray_alloc(PyByteArrayObject *self) 2754 bytearray_alloc(PyByteArrayObject *self)
2580 { 2755 {
2581 return PyInt_FromSsize_t(self->ob_alloc); 2756 return PyLong_FromSsize_t(self->ob_alloc);
2582 } 2757 }
2583 2758
2584 PyDoc_STRVAR(join_doc, 2759 /*[clinic input]
2585 "B.join(iterable_of_bytes) -> bytes\n\ 2760 bytearray.join
2586 \n\ 2761
2587 Concatenates any number of bytearray objects, with B in between each pair."); 2762 iterable_of_bytes: object
2588 2763 /
2589 static PyObject * 2764
2590 bytearray_join(PyByteArrayObject *self, PyObject *it) 2765 Concatenate any number of bytes/bytearray objects.
2591 { 2766
2592 PyObject *seq; 2767 The bytearray whose method is called is inserted in between each pair.
2593 Py_ssize_t mysize = Py_SIZE(self); 2768
2594 Py_ssize_t i; 2769 The result is returned as a new bytearray object.
2595 Py_ssize_t n; 2770 [clinic start generated code]*/
2596 PyObject **items; 2771
2597 Py_ssize_t totalsize = 0; 2772 static PyObject *
2598 PyObject *result; 2773 bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
2599 char *dest; 2774 /*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
2600 2775 {
2601 seq = PySequence_Fast(it, "can only join an iterable"); 2776 return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
2602 if (seq == NULL) 2777 }
2603 return NULL; 2778
2604 n = PySequence_Fast_GET_SIZE(seq); 2779 /*[clinic input]
2605 items = PySequence_Fast_ITEMS(seq); 2780 bytearray.splitlines
2606 2781
2607 /* Compute the total size, and check that they are all bytes */ 2782 keepends: int(c_default="0") = False
2608 /* XXX Shouldn't we use _getbuffer() on these items instead? */ 2783
2609 for (i = 0; i < n; i++) { 2784 Return a list of the lines in the bytearray, breaking at line boundaries.
2610 PyObject *obj = items[i]; 2785
2611 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) { 2786 Line breaks are not included in the resulting list unless keepends is given and
2612 PyErr_Format(PyExc_TypeError, 2787 true.
2613 "can only join an iterable of bytes " 2788 [clinic start generated code]*/
2614 "(item %ld has type '%.100s')", 2789
2615 /* XXX %ld isn't right on Win64 */ 2790 static PyObject *
2616 (long)i, Py_TYPE(obj)->tp_name); 2791 bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
2617 goto error; 2792 /*[clinic end generated code: output=4223c94b895f6ad9 input=8ccade941e5ea0bd]*/
2618 } 2793 {
2619 if (i > 0)
2620 totalsize += mysize;
2621 totalsize += Py_SIZE(obj);
2622 if (totalsize < 0) {
2623 PyErr_NoMemory();
2624 goto error;
2625 }
2626 }
2627
2628 /* Allocate the result, and copy the bytes */
2629 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2630 if (result == NULL)
2631 goto error;
2632 dest = PyByteArray_AS_STRING(result);
2633 for (i = 0; i < n; i++) {
2634 PyObject *obj = items[i];
2635 Py_ssize_t size = Py_SIZE(obj);
2636 char *buf;
2637 if (PyByteArray_Check(obj))
2638 buf = PyByteArray_AS_STRING(obj);
2639 else
2640 buf = PyBytes_AS_STRING(obj);
2641 if (i) {
2642 memcpy(dest, self->ob_bytes, mysize);
2643 dest += mysize;
2644 }
2645 memcpy(dest, buf, size);
2646 dest += size;
2647 }
2648
2649 /* Done */
2650 Py_DECREF(seq);
2651 return result;
2652
2653 /* Error handling */
2654 error:
2655 Py_DECREF(seq);
2656 return NULL;
2657 }
2658
2659 PyDoc_STRVAR(splitlines__doc__,
2660 "B.splitlines(keepends=False) -> list of lines\n\
2661 \n\
2662 Return a list of the lines in B, breaking at line boundaries.\n\
2663 Line breaks are not included in the resulting list unless keepends\n\
2664 is given and true.");
2665
2666 static PyObject*
2667 bytearray_splitlines(PyObject *self, PyObject *args)
2668 {
2669 int keepends = 0;
2670
2671 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2672 return NULL;
2673
2674 return stringlib_splitlines( 2794 return stringlib_splitlines(
2675 (PyObject*) self, PyByteArray_AS_STRING(self), 2795 (PyObject*) self, PyByteArray_AS_STRING(self),
2676 PyByteArray_GET_SIZE(self), keepends 2796 PyByteArray_GET_SIZE(self), keepends
2677 ); 2797 );
2678 } 2798 }
2679 2799
2680 PyDoc_STRVAR(fromhex_doc,
2681 "bytearray.fromhex(string) -> bytearray\n\
2682 \n\
2683 Create a bytearray object from a string of hexadecimal numbers.\n\
2684 Spaces between two numbers are accepted.\n\
2685 Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2686
2687 static int 2800 static int
2688 hex_digit_to_int(char c) 2801 hex_digit_to_int(Py_UCS4 c)
2689 { 2802 {
2803 if (c >= 128)
2804 return -1;
2690 if (Py_ISDIGIT(c)) 2805 if (Py_ISDIGIT(c))
2691 return c - '0'; 2806 return c - '0';
2692 else { 2807 else {
2693 if (Py_ISUPPER(c)) 2808 if (Py_ISUPPER(c))
2694 c = Py_TOLOWER(c); 2809 c = Py_TOLOWER(c);
2695 if (c >= 'a' && c <= 'f') 2810 if (c >= 'a' && c <= 'f')
2696 return c - 'a' + 10; 2811 return c - 'a' + 10;
2697 } 2812 }
2698 return -1; 2813 return -1;
2699 } 2814 }
2700 2815
2701 static PyObject * 2816 /*[clinic input]
2702 bytearray_fromhex(PyObject *cls, PyObject *args) 2817 @classmethod
2818 bytearray.fromhex
2819
2820 cls: self(type="PyObject*")
2821 string: unicode
2822 /
2823
2824 Create a bytearray object from a string of hexadecimal numbers.
2825
2826 Spaces between two numbers are accepted.
2827 Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
2828 [clinic start generated code]*/
2829
2830 static PyObject *
2831 bytearray_fromhex_impl(PyObject*cls, PyObject *string)
2832 /*[clinic end generated code: output=df3da60129b3700c input=907bbd2d34d9367a]*/
2703 { 2833 {
2704 PyObject *newbytes; 2834 PyObject *newbytes;
2705 char *buf; 2835 char *buf;
2706 char *hex;
2707 Py_ssize_t hexlen, byteslen, i, j; 2836 Py_ssize_t hexlen, byteslen, i, j;
2708 int top, bot; 2837 int top, bot;
2709 2838 void *data;
2710 if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen)) 2839 unsigned int kind;
2711 return NULL; 2840
2841 assert(PyUnicode_Check(string));
2842 if (PyUnicode_READY(string))
2843 return NULL;
2844 kind = PyUnicode_KIND(string);
2845 data = PyUnicode_DATA(string);
2846 hexlen = PyUnicode_GET_LENGTH(string);
2847
2712 byteslen = hexlen/2; /* This overestimates if there are spaces */ 2848 byteslen = hexlen/2; /* This overestimates if there are spaces */
2713 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen); 2849 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2714 if (!newbytes) 2850 if (!newbytes)
2715 return NULL; 2851 return NULL;
2716 buf = PyByteArray_AS_STRING(newbytes); 2852 buf = PyByteArray_AS_STRING(newbytes);
2717 for (i = j = 0; i < hexlen; i += 2) { 2853 for (i = j = 0; i < hexlen; i += 2) {
2718 /* skip over spaces in the input */ 2854 /* skip over spaces in the input */
2719 while (hex[i] == ' ') 2855 while (PyUnicode_READ(kind, data, i) == ' ')
2720 i++; 2856 i++;
2721 if (i >= hexlen) 2857 if (i >= hexlen)
2722 break; 2858 break;
2723 top = hex_digit_to_int(hex[i]); 2859 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
2724 bot = hex_digit_to_int(hex[i+1]); 2860 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
2725 if (top == -1 || bot == -1) { 2861 if (top == -1 || bot == -1) {
2726 PyErr_Format(PyExc_ValueError, 2862 PyErr_Format(PyExc_ValueError,
2727 "non-hexadecimal number found in " 2863 "non-hexadecimal number found in "
2728 "fromhex() arg at position %zd", i); 2864 "fromhex() arg at position %zd", i);
2729 goto error; 2865 goto error;
2730 } 2866 }
2731 buf[j++] = (top << 4) + bot; 2867 buf[j++] = (top << 4) + bot;
2732 } 2868 }
2733 if (PyByteArray_Resize(newbytes, j) < 0) 2869 if (PyByteArray_Resize(newbytes, j) < 0)
2734 goto error; 2870 goto error;
2735 return newbytes; 2871 return newbytes;
2736 2872
2737 error: 2873 error:
2738 Py_DECREF(newbytes); 2874 Py_DECREF(newbytes);
2739 return NULL; 2875 return NULL;
2740 } 2876 }
2741 2877
2742 PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); 2878 PyDoc_STRVAR(hex__doc__,
2743 2879 "B.hex() -> string\n\
2744 static PyObject * 2880 \n\
2745 bytearray_reduce(PyByteArrayObject *self) 2881 Create a string of hexadecimal numbers from a bytearray object.\n\
2746 { 2882 Example: bytearray([0xb9, 0x01, 0xef]).hex() -> 'b901ef'.");
2747 PyObject *latin1, *dict; 2883
2748 if (self->ob_bytes) 2884 static PyObject *
2749 #ifdef Py_USING_UNICODE 2885 bytearray_hex(PyBytesObject *self)
2750 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes, 2886 {
2751 Py_SIZE(self), NULL); 2887 char* argbuf = PyByteArray_AS_STRING(self);
2752 #else 2888 Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
2753 latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self)); 2889 return _Py_strhex(argbuf, arglen);
2754 #endif 2890 }
2755 else 2891
2756 #ifdef Py_USING_UNICODE 2892 static PyObject *
2757 latin1 = PyUnicode_FromString(""); 2893 _common_reduce(PyByteArrayObject *self, int proto)
2758 #else 2894 {
2759 latin1 = PyString_FromString(""); 2895 PyObject *dict;
2760 #endif 2896 _Py_IDENTIFIER(__dict__);
2761 2897 char *buf;
2762 dict = PyObject_GetAttrString((PyObject *)self, "__dict__"); 2898
2899 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
2763 if (dict == NULL) { 2900 if (dict == NULL) {
2764 PyErr_Clear(); 2901 PyErr_Clear();
2765 dict = Py_None; 2902 dict = Py_None;
2766 Py_INCREF(dict); 2903 Py_INCREF(dict);
2767 } 2904 }
2768 2905
2769 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict); 2906 buf = PyByteArray_AS_STRING(self);
2770 } 2907 if (proto < 3) {
2771 2908 /* use str based reduction for backwards compatibility with Python 2.x * /
2772 PyDoc_STRVAR(sizeof_doc, 2909 PyObject *latin1;
2773 "B.__sizeof__() -> int\n\ 2910 if (Py_SIZE(self))
2774 \n\ 2911 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
2775 Returns the size of B in memory, in bytes"); 2912 else
2776 static PyObject * 2913 latin1 = PyUnicode_FromString("");
2777 bytearray_sizeof(PyByteArrayObject *self) 2914 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict) ;
2915 }
2916 else {
2917 /* use more efficient byte based reduction */
2918 if (Py_SIZE(self)) {
2919 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
2920 }
2921 else {
2922 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2923 }
2924 }
2925 }
2926
2927 /*[clinic input]
2928 bytearray.__reduce__ as bytearray_reduce
2929
2930 self: self(type="PyByteArrayObject *")
2931
2932 Return state information for pickling.
2933 [clinic start generated code]*/
2934
2935 static PyObject *
2936 bytearray_reduce_impl(PyByteArrayObject *self)
2937 /*[clinic end generated code: output=52bf304086464cab input=fbb07de4d102a03a]*/
2938 {
2939 return _common_reduce(self, 2);
2940 }
2941
2942 /*[clinic input]
2943 bytearray.__reduce_ex__ as bytearray_reduce_ex
2944
2945 self: self(type="PyByteArrayObject *")
2946 proto: int = 0
2947 /
2948
2949 Return state information for pickling.
2950 [clinic start generated code]*/
2951
2952 static PyObject *
2953 bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
2954 /*[clinic end generated code: output=52eac33377197520 input=0e091a42ca6dbd91]*/
2955 {
2956 return _common_reduce(self, proto);
2957 }
2958
2959 /*[clinic input]
2960 bytearray.__sizeof__ as bytearray_sizeof
2961
2962 self: self(type="PyByteArrayObject *")
2963
2964 Returns the size of the bytearray object in memory, in bytes.
2965 [clinic start generated code]*/
2966
2967 static PyObject *
2968 bytearray_sizeof_impl(PyByteArrayObject *self)
2969 /*[clinic end generated code: output=738abdd17951c427 input=6b23d305362b462b]*/
2778 { 2970 {
2779 Py_ssize_t res; 2971 Py_ssize_t res;
2780 2972
2781 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); 2973 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2782 return PyInt_FromSsize_t(res); 2974 return PyLong_FromSsize_t(res);
2783 } 2975 }
2784 2976
2785 static PySequenceMethods bytearray_as_sequence = { 2977 static PySequenceMethods bytearray_as_sequence = {
2786 (lenfunc)bytearray_length, /* sq_length */ 2978 (lenfunc)bytearray_length, /* sq_length */
2787 (binaryfunc)PyByteArray_Concat, /* sq_concat */ 2979 (binaryfunc)PyByteArray_Concat, /* sq_concat */
2788 (ssizeargfunc)bytearray_repeat, /* sq_repeat */ 2980 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2789 (ssizeargfunc)bytearray_getitem, /* sq_item */ 2981 (ssizeargfunc)bytearray_getitem, /* sq_item */
2790 0, /* sq_slice */ 2982 0, /* sq_slice */
2791 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */ 2983 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2792 0, /* sq_ass_slice */ 2984 0, /* sq_ass_slice */
2793 (objobjproc)bytearray_contains, /* sq_contains */ 2985 (objobjproc)bytearray_contains, /* sq_contains */
2794 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */ 2986 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2795 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */ 2987 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
2796 }; 2988 };
2797 2989
2798 static PyMappingMethods bytearray_as_mapping = { 2990 static PyMappingMethods bytearray_as_mapping = {
2799 (lenfunc)bytearray_length, 2991 (lenfunc)bytearray_length,
2800 (binaryfunc)bytearray_subscript, 2992 (binaryfunc)bytearray_subscript,
2801 (objobjargproc)bytearray_ass_subscript, 2993 (objobjargproc)bytearray_ass_subscript,
2802 }; 2994 };
2803 2995
2804 static PyBufferProcs bytearray_as_buffer = { 2996 static PyBufferProcs bytearray_as_buffer = {
2805 (readbufferproc)bytearray_buffer_getreadbuf,
2806 (writebufferproc)bytearray_buffer_getwritebuf,
2807 (segcountproc)bytearray_buffer_getsegcount,
2808 (charbufferproc)bytearray_buffer_getcharbuf,
2809 (getbufferproc)bytearray_getbuffer, 2997 (getbufferproc)bytearray_getbuffer,
2810 (releasebufferproc)bytearray_releasebuffer, 2998 (releasebufferproc)bytearray_releasebuffer,
2811 }; 2999 };
2812 3000
2813 static PyMethodDef 3001 static PyMethodDef
2814 bytearray_methods[] = { 3002 bytearray_methods[] = {
2815 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, 3003 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2816 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc}, 3004 BYTEARRAY_REDUCE_METHODDEF
2817 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc}, 3005 BYTEARRAY_REDUCE_EX_METHODDEF
2818 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__}, 3006 BYTEARRAY_SIZEOF_METHODDEF
3007 BYTEARRAY_APPEND_METHODDEF
2819 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, 3008 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2820 _Py_capitalize__doc__}, 3009 _Py_capitalize__doc__},
2821 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, 3010 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
3011 BYTEARRAY_CLEAR_METHODDEF
3012 BYTEARRAY_COPY_METHODDEF
2822 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__}, 3013 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
2823 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, deco de_doc}, 3014 BYTEARRAY_DECODE_METHODDEF
2824 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__} , 3015 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__} ,
2825 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, 3016 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWOR DS,
2826 expandtabs__doc__}, 3017 expandtabs__doc__},
2827 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__}, 3018 BYTEARRAY_EXTEND_METHODDEF
2828 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__}, 3019 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2829 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, 3020 BYTEARRAY_FROMHEX_METHODDEF
2830 fromhex_doc}, 3021 {"hex", (PyCFunction)bytearray_hex, METH_NOARGS, hex__doc__},
2831 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__}, 3022 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2832 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__}, 3023 BYTEARRAY_INSERT_METHODDEF
2833 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, 3024 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2834 _Py_isalnum__doc__}, 3025 _Py_isalnum__doc__},
2835 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, 3026 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2836 _Py_isalpha__doc__}, 3027 _Py_isalpha__doc__},
2837 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS, 3028 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2838 _Py_isdigit__doc__}, 3029 _Py_isdigit__doc__},
2839 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS, 3030 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2840 _Py_islower__doc__}, 3031 _Py_islower__doc__},
2841 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS, 3032 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2842 _Py_isspace__doc__}, 3033 _Py_isspace__doc__},
2843 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS, 3034 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2844 _Py_istitle__doc__}, 3035 _Py_istitle__doc__},
2845 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, 3036 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2846 _Py_isupper__doc__}, 3037 _Py_isupper__doc__},
2847 {"join", (PyCFunction)bytearray_join, METH_O, join_doc}, 3038 BYTEARRAY_JOIN_METHODDEF
2848 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, 3039 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2849 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, 3040 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
2850 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__}, 3041 BYTEARRAY_LSTRIP_METHODDEF
2851 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__}, 3042 BYTEARRAY_MAKETRANS_METHODDEF
2852 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__}, 3043 BYTEARRAY_PARTITION_METHODDEF
2853 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__}, 3044 BYTEARRAY_POP_METHODDEF
2854 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__}, 3045 BYTEARRAY_REMOVE_METHODDEF
2855 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__}, 3046 BYTEARRAY_REPLACE_METHODDEF
3047 BYTEARRAY_REVERSE_METHODDEF
2856 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__}, 3048 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2857 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__}, 3049 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
2858 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, 3050 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
2859 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__} , 3051 BYTEARRAY_RPARTITION_METHODDEF
2860 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__}, 3052 BYTEARRAY_RSPLIT_METHODDEF
2861 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__}, 3053 BYTEARRAY_RSTRIP_METHODDEF
2862 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__}, 3054 BYTEARRAY_SPLIT_METHODDEF
2863 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS, 3055 BYTEARRAY_SPLITLINES_METHODDEF
2864 splitlines__doc__},
2865 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , 3056 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
2866 startswith__doc__}, 3057 startswith__doc__},
2867 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__}, 3058 BYTEARRAY_STRIP_METHODDEF
2868 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, 3059 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2869 _Py_swapcase__doc__}, 3060 _Py_swapcase__doc__},
2870 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, 3061 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
2871 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, 3062 BYTEARRAY_TRANSLATE_METHODDEF
2872 translate__doc__},
2873 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, 3063 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2874 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, 3064 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2875 {NULL} 3065 {NULL}
2876 }; 3066 };
2877 3067
3068 static PyObject *
3069 bytearray_mod(PyObject *v, PyObject *w)
3070 {
3071 if (!PyByteArray_Check(v))
3072 Py_RETURN_NOTIMPLEMENTED;
3073 return bytearray_format((PyByteArrayObject *)v, w);
3074 }
3075
3076 static PyNumberMethods bytearray_as_number = {
3077 0, /*nb_add*/
3078 0, /*nb_subtract*/
3079 0, /*nb_multiply*/
3080 bytearray_mod, /*nb_remainder*/
3081 };
3082
2878 PyDoc_STRVAR(bytearray_doc, 3083 PyDoc_STRVAR(bytearray_doc,
2879 "bytearray(iterable_of_ints) -> bytearray.\n\ 3084 "bytearray(iterable_of_ints) -> bytearray\n\
2880 bytearray(string, encoding[, errors]) -> bytearray.\n\ 3085 bytearray(string, encoding[, errors]) -> bytearray\n\
2881 bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\ 3086 bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2882 bytearray(memory_view) -> bytearray.\n\ 3087 bytearray(int) -> bytes array of size given by the parameter initialized with nu ll bytes\n\
3088 bytearray() -> empty bytes array\n\
2883 \n\ 3089 \n\
2884 Construct an mutable bytearray object from:\n\ 3090 Construct an mutable bytearray object from:\n\
2885 - an iterable yielding integers in range(256)\n\ 3091 - an iterable yielding integers in range(256)\n\
2886 - a text string encoded using the specified encoding\n\ 3092 - a text string encoded using the specified encoding\n\
2887 - a bytes or a bytearray object\n\ 3093 - a bytes or a buffer object\n\
2888 - any object implementing the buffer API.\n\ 3094 - any object implementing the buffer API.\n\
2889 \n\ 3095 - an integer");
2890 bytearray(int) -> bytearray.\n\
2891 \n\
2892 Construct a zero-initialized bytearray of the given length.");
2893 3096
2894 3097
2895 static PyObject *bytearray_iter(PyObject *seq); 3098 static PyObject *bytearray_iter(PyObject *seq);
2896 3099
2897 PyTypeObject PyByteArray_Type = { 3100 PyTypeObject PyByteArray_Type = {
2898 PyVarObject_HEAD_INIT(&PyType_Type, 0) 3101 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2899 "bytearray", 3102 "bytearray",
2900 sizeof(PyByteArrayObject), 3103 sizeof(PyByteArrayObject),
2901 0, 3104 0,
2902 (destructor)bytearray_dealloc, /* tp_dealloc */ 3105 (destructor)bytearray_dealloc, /* tp_dealloc */
2903 0, /* tp_print */ 3106 0, /* tp_print */
2904 0, /* tp_getattr */ 3107 0, /* tp_getattr */
2905 0, /* tp_setattr */ 3108 0, /* tp_setattr */
2906 0, /* tp_compare */ 3109 0, /* tp_reserved */
2907 (reprfunc)bytearray_repr, /* tp_repr */ 3110 (reprfunc)bytearray_repr, /* tp_repr */
2908 0, /* tp_as_number */ 3111 &bytearray_as_number, /* tp_as_number */
2909 &bytearray_as_sequence, /* tp_as_sequence */ 3112 &bytearray_as_sequence, /* tp_as_sequence */
2910 &bytearray_as_mapping, /* tp_as_mapping */ 3113 &bytearray_as_mapping, /* tp_as_mapping */
2911 0, /* tp_hash */ 3114 0, /* tp_hash */
2912 0, /* tp_call */ 3115 0, /* tp_call */
2913 bytearray_str, /* tp_str */ 3116 bytearray_str, /* tp_str */
2914 PyObject_GenericGetAttr, /* tp_getattro */ 3117 PyObject_GenericGetAttr, /* tp_getattro */
2915 0, /* tp_setattro */ 3118 0, /* tp_setattro */
2916 &bytearray_as_buffer, /* tp_as_buffer */ 3119 &bytearray_as_buffer, /* tp_as_buffer */
2917 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | 3120 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2918 Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
2919 bytearray_doc, /* tp_doc */ 3121 bytearray_doc, /* tp_doc */
2920 0, /* tp_traverse */ 3122 0, /* tp_traverse */
2921 0, /* tp_clear */ 3123 0, /* tp_clear */
2922 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */ 3124 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
2923 0, /* tp_weaklistoffset */ 3125 0, /* tp_weaklistoffset */
2924 bytearray_iter, /* tp_iter */ 3126 bytearray_iter, /* tp_iter */
2925 0, /* tp_iternext */ 3127 0, /* tp_iternext */
2926 bytearray_methods, /* tp_methods */ 3128 bytearray_methods, /* tp_methods */
2927 0, /* tp_members */ 3129 0, /* tp_members */
2928 0, /* tp_getset */ 3130 0, /* tp_getset */
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2966 PyByteArrayObject *seq; 3168 PyByteArrayObject *seq;
2967 PyObject *item; 3169 PyObject *item;
2968 3170
2969 assert(it != NULL); 3171 assert(it != NULL);
2970 seq = it->it_seq; 3172 seq = it->it_seq;
2971 if (seq == NULL) 3173 if (seq == NULL)
2972 return NULL; 3174 return NULL;
2973 assert(PyByteArray_Check(seq)); 3175 assert(PyByteArray_Check(seq));
2974 3176
2975 if (it->it_index < PyByteArray_GET_SIZE(seq)) { 3177 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2976 item = PyInt_FromLong( 3178 item = PyLong_FromLong(
2977 (unsigned char)seq->ob_bytes[it->it_index]); 3179 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
2978 if (item != NULL) 3180 if (item != NULL)
2979 ++it->it_index; 3181 ++it->it_index;
2980 return item; 3182 return item;
2981 } 3183 }
2982 3184
2983 Py_DECREF(seq); 3185 Py_DECREF(seq);
2984 it->it_seq = NULL; 3186 it->it_seq = NULL;
2985 return NULL; 3187 return NULL;
2986 } 3188 }
2987 3189
2988 static PyObject * 3190 static PyObject *
2989 bytesarrayiter_length_hint(bytesiterobject *it) 3191 bytearrayiter_length_hint(bytesiterobject *it)
2990 { 3192 {
2991 Py_ssize_t len = 0; 3193 Py_ssize_t len = 0;
2992 if (it->it_seq) 3194 if (it->it_seq)
2993 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index; 3195 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2994 return PyInt_FromSsize_t(len); 3196 return PyLong_FromSsize_t(len);
2995 } 3197 }
2996 3198
2997 PyDoc_STRVAR(length_hint_doc, 3199 PyDoc_STRVAR(length_hint_doc,
2998 "Private method returning an estimate of len(list(it))."); 3200 "Private method returning an estimate of len(list(it)).");
2999 3201
3202 static PyObject *
3203 bytearrayiter_reduce(bytesiterobject *it)
3204 {
3205 if (it->it_seq != NULL) {
3206 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
3207 it->it_seq, it->it_index);
3208 } else {
3209 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
3210 if (u == NULL)
3211 return NULL;
3212 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
3213 }
3214 }
3215
3216 static PyObject *
3217 bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3218 {
3219 Py_ssize_t index = PyLong_AsSsize_t(state);
3220 if (index == -1 && PyErr_Occurred())
3221 return NULL;
3222 if (it->it_seq != NULL) {
3223 if (index < 0)
3224 index = 0;
3225 else if (index > PyByteArray_GET_SIZE(it->it_seq))
3226 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
3227 it->it_index = index;
3228 }
3229 Py_RETURN_NONE;
3230 }
3231
3232 PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3233
3000 static PyMethodDef bytearrayiter_methods[] = { 3234 static PyMethodDef bytearrayiter_methods[] = {
3001 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS, 3235 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
3002 length_hint_doc}, 3236 length_hint_doc},
3237 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
3238 bytearray_reduce__doc__},
3239 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3240 setstate_doc},
3003 {NULL, NULL} /* sentinel */ 3241 {NULL, NULL} /* sentinel */
3004 }; 3242 };
3005 3243
3006 PyTypeObject PyByteArrayIter_Type = { 3244 PyTypeObject PyByteArrayIter_Type = {
3007 PyVarObject_HEAD_INIT(&PyType_Type, 0) 3245 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3008 "bytearray_iterator", /* tp_name */ 3246 "bytearray_iterator", /* tp_name */
3009 sizeof(bytesiterobject), /* tp_basicsize */ 3247 sizeof(bytesiterobject), /* tp_basicsize */
3010 0, /* tp_itemsize */ 3248 0, /* tp_itemsize */
3011 /* methods */ 3249 /* methods */
3012 (destructor)bytearrayiter_dealloc, /* tp_dealloc */ 3250 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
3013 0, /* tp_print */ 3251 0, /* tp_print */
3014 0, /* tp_getattr */ 3252 0, /* tp_getattr */
3015 0, /* tp_setattr */ 3253 0, /* tp_setattr */
3016 0, /* tp_compare */ 3254 0, /* tp_reserved */
3017 0, /* tp_repr */ 3255 0, /* tp_repr */
3018 0, /* tp_as_number */ 3256 0, /* tp_as_number */
3019 0, /* tp_as_sequence */ 3257 0, /* tp_as_sequence */
3020 0, /* tp_as_mapping */ 3258 0, /* tp_as_mapping */
3021 0, /* tp_hash */ 3259 0, /* tp_hash */
3022 0, /* tp_call */ 3260 0, /* tp_call */
3023 0, /* tp_str */ 3261 0, /* tp_str */
3024 PyObject_GenericGetAttr, /* tp_getattro */ 3262 PyObject_GenericGetAttr, /* tp_getattro */
3025 0, /* tp_setattro */ 3263 0, /* tp_setattro */
3026 0, /* tp_as_buffer */ 3264 0, /* tp_as_buffer */
(...skipping 20 matching lines...) Expand all
3047 } 3285 }
3048 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type); 3286 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3049 if (it == NULL) 3287 if (it == NULL)
3050 return NULL; 3288 return NULL;
3051 it->it_index = 0; 3289 it->it_index = 0;
3052 Py_INCREF(seq); 3290 Py_INCREF(seq);
3053 it->it_seq = (PyByteArrayObject *)seq; 3291 it->it_seq = (PyByteArrayObject *)seq;
3054 _PyObject_GC_TRACK(it); 3292 _PyObject_GC_TRACK(it);
3055 return (PyObject *)it; 3293 return (PyObject *)it;
3056 } 3294 }
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+