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

Delta Between Two Patch Sets: Objects/bytearrayobject.c

Issue 11828: startswith and endswith don't accept None as slice index
Left Patch Set: Created 2 years, 1 month ago
Right Patch Set: Created 2 years, 1 month 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') | Objects/bytesobject.c » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* PyByteArray (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 7
8 static PyByteArrayObject *nullbytes = NULL;
8 char _PyByteArray_empty_string[] = ""; 9 char _PyByteArray_empty_string[] = "";
9 10
10 void 11 void
11 PyByteArray_Fini(void) 12 PyByteArray_Fini(void)
12 { 13 {
14 Py_CLEAR(nullbytes);
13 } 15 }
14 16
15 int 17 int
16 PyByteArray_Init(void) 18 PyByteArray_Init(void)
17 { 19 {
20 nullbytes = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
21 if (nullbytes == NULL)
22 return 0;
23 nullbytes->ob_bytes = NULL;
24 Py_SIZE(nullbytes) = nullbytes->ob_alloc = 0;
25 nullbytes->ob_exports = 0;
18 return 1; 26 return 1;
19 } 27 }
20 28
21 /* end nullbytes support */ 29 /* end nullbytes support */
22 30
23 /* Helpers */ 31 /* Helpers */
24 32
25 static int 33 static int
26 _getbytevalue(PyObject* arg, int *value) 34 _getbytevalue(PyObject* arg, int *value)
27 { 35 {
28 long face_value; 36 long face_value;
29 37
30 if (PyLong_Check(arg)) { 38 if (PyLong_Check(arg)) {
31 face_value = PyLong_AsLong(arg); 39 face_value = PyLong_AsLong(arg);
32 } else { 40 } else {
33 PyObject *index = PyNumber_Index(arg); 41 PyObject *index = PyNumber_Index(arg);
34 if (index == NULL) { 42 if (index == NULL) {
35 PyErr_Format(PyExc_TypeError, "an integer is required"); 43 PyErr_Format(PyExc_TypeError, "an integer is required");
36 *value = -1;
37 return 0; 44 return 0;
38 } 45 }
39 face_value = PyLong_AsLong(index); 46 face_value = PyLong_AsLong(index);
40 Py_DECREF(index); 47 Py_DECREF(index);
41 } 48 }
42 49
43 if (face_value < 0 || face_value >= 256) { 50 if (face_value < 0 || face_value >= 256) {
44 /* this includes the OverflowError in case the long is too large */ 51 /* this includes the OverflowError in case the long is too large */
45 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); 52 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
46 *value = -1;
47 return 0; 53 return 0;
48 } 54 }
49 55
50 *value = face_value; 56 *value = face_value;
51 return 1; 57 return 1;
52 } 58 }
53 59
54 static int 60 static int
55 bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) 61 bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
56 { 62 {
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 static PyObject * 309 static PyObject *
304 bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) 310 bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
305 { 311 {
306 PyByteArrayObject *result; 312 PyByteArrayObject *result;
307 Py_ssize_t mysize; 313 Py_ssize_t mysize;
308 Py_ssize_t size; 314 Py_ssize_t size;
309 315
310 if (count < 0) 316 if (count < 0)
311 count = 0; 317 count = 0;
312 mysize = Py_SIZE(self); 318 mysize = Py_SIZE(self);
313 if (count > 0 && mysize > PY_SSIZE_T_MAX / count) 319 size = mysize * count;
320 if (count != 0 && size / count != mysize)
314 return PyErr_NoMemory(); 321 return PyErr_NoMemory();
315 size = mysize * count;
316 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); 322 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
317 if (result != NULL && size != 0) { 323 if (result != NULL && size != 0) {
318 if (mysize == 1) 324 if (mysize == 1)
319 memset(result->ob_bytes, self->ob_bytes[0], size); 325 memset(result->ob_bytes, self->ob_bytes[0], size);
320 else { 326 else {
321 Py_ssize_t i; 327 Py_ssize_t i;
322 for (i = 0; i < count; i++) 328 for (i = 0; i < count; i++)
323 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize); 329 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
324 } 330 }
325 } 331 }
326 return (PyObject *)result; 332 return (PyObject *)result;
327 } 333 }
328 334
329 static PyObject * 335 static PyObject *
330 bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) 336 bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
331 { 337 {
332 Py_ssize_t mysize; 338 Py_ssize_t mysize;
333 Py_ssize_t size; 339 Py_ssize_t size;
334 340
335 if (count < 0) 341 if (count < 0)
336 count = 0; 342 count = 0;
337 mysize = Py_SIZE(self); 343 mysize = Py_SIZE(self);
338 if (count > 0 && mysize > PY_SSIZE_T_MAX / count) 344 size = mysize * count;
345 if (count != 0 && size / count != mysize)
339 return PyErr_NoMemory(); 346 return PyErr_NoMemory();
340 size = mysize * count;
341 if (size < self->ob_alloc) { 347 if (size < self->ob_alloc) {
342 Py_SIZE(self) = size; 348 Py_SIZE(self) = size;
343 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */ 349 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
344 } 350 }
345 else if (PyByteArray_Resize((PyObject *)self, size) < 0) 351 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
346 return NULL; 352 return NULL;
347 353
348 if (mysize == 1) 354 if (mysize == 1)
349 memset(self->ob_bytes, self->ob_bytes[0], size); 355 memset(self->ob_bytes, self->ob_bytes[0], size);
350 else { 356 else {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 i += PyByteArray_GET_SIZE(self); 388 i += PyByteArray_GET_SIZE(self);
383 389
384 if (i < 0 || i >= Py_SIZE(self)) { 390 if (i < 0 || i >= Py_SIZE(self)) {
385 PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); 391 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
386 return NULL; 392 return NULL;
387 } 393 }
388 return PyLong_FromLong((unsigned char)(self->ob_bytes[i])); 394 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
389 } 395 }
390 else if (PySlice_Check(index)) { 396 else if (PySlice_Check(index)) {
391 Py_ssize_t start, stop, step, slicelength, cur, i; 397 Py_ssize_t start, stop, step, slicelength, cur, i;
392 if (PySlice_GetIndicesEx(index, 398 if (PySlice_GetIndicesEx((PySliceObject *)index,
393 PyByteArray_GET_SIZE(self), 399 PyByteArray_GET_SIZE(self),
394 &start, &stop, &step, &slicelength) < 0) { 400 &start, &stop, &step, &slicelength) < 0) {
395 return NULL; 401 return NULL;
396 } 402 }
397 403
398 if (slicelength <= 0) 404 if (slicelength <= 0)
399 return PyByteArray_FromStringAndSize("", 0); 405 return PyByteArray_FromStringAndSize("", 0);
400 else if (step == 1) { 406 else if (step == 1) {
401 return PyByteArray_FromStringAndSize(self->ob_bytes + start, 407 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
402 slicelength); 408 slicelength);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 } 572 }
567 else { 573 else {
568 int ival; 574 int ival;
569 if (!_getbytevalue(values, &ival)) 575 if (!_getbytevalue(values, &ival))
570 return -1; 576 return -1;
571 self->ob_bytes[i] = (char)ival; 577 self->ob_bytes[i] = (char)ival;
572 return 0; 578 return 0;
573 } 579 }
574 } 580 }
575 else if (PySlice_Check(index)) { 581 else if (PySlice_Check(index)) {
576 if (PySlice_GetIndicesEx(index, 582 if (PySlice_GetIndicesEx((PySliceObject *)index,
577 PyByteArray_GET_SIZE(self), 583 PyByteArray_GET_SIZE(self),
578 &start, &stop, &step, &slicelen) < 0) { 584 &start, &stop, &step, &slicelen) < 0) {
579 return -1; 585 return -1;
580 } 586 }
581 } 587 }
582 else { 588 else {
583 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer"); 589 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
584 return -1; 590 return -1;
585 } 591 }
586 592
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 return 0; 648 return 0;
643 } 649 }
644 else { 650 else {
645 if (needed == 0) { 651 if (needed == 0) {
646 /* Delete slice */ 652 /* Delete slice */
647 size_t cur; 653 size_t cur;
648 Py_ssize_t i; 654 Py_ssize_t i;
649 655
650 if (!_canresize(self)) 656 if (!_canresize(self))
651 return -1; 657 return -1;
652
653 if (slicelen == 0)
654 /* Nothing to do here. */
655 return 0;
656
657 if (step < 0) { 658 if (step < 0) {
658 stop = start + 1; 659 stop = start + 1;
659 start = stop + step * (slicelen - 1) - 1; 660 start = stop + step * (slicelen - 1) - 1;
660 step = -step; 661 step = -step;
661 } 662 }
662 for (cur = start, i = 0; 663 for (cur = start, i = 0;
663 i < slicelen; cur += step, i++) { 664 i < slicelen; cur += step, i++) {
664 Py_ssize_t lim = step - 1; 665 Py_ssize_t lim = step - 1;
665 666
666 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self)) 667 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
667 lim = PyByteArray_GET_SIZE(self) - cur - 1; 668 lim = PyByteArray_GET_SIZE(self) - cur - 1;
668 669
669 memmove(self->ob_bytes + cur - i, 670 memmove(self->ob_bytes + cur - i,
670 self->ob_bytes + cur + 1, lim); 671 self->ob_bytes + cur + 1, lim);
671 } 672 }
672 /* Move the tail of the bytes, in one chunk */ 673 /* Move the tail of the bytes, in one chunk */
673 cur = start + (size_t)slicelen*step; 674 cur = start + slicelen*step;
674 if (cur < (size_t)PyByteArray_GET_SIZE(self)) { 675 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
675 memmove(self->ob_bytes + cur - slicelen, 676 memmove(self->ob_bytes + cur - slicelen,
676 self->ob_bytes + cur, 677 self->ob_bytes + cur,
677 PyByteArray_GET_SIZE(self) - cur); 678 PyByteArray_GET_SIZE(self) - cur);
678 } 679 }
679 if (PyByteArray_Resize((PyObject *)self, 680 if (PyByteArray_Resize((PyObject *)self,
680 PyByteArray_GET_SIZE(self) - slicelen) < 0) 681 PyByteArray_GET_SIZE(self) - slicelen) < 0)
681 return -1; 682 return -1;
682 683
683 return 0; 684 return 0;
684 } 685 }
685 else { 686 else {
686 /* Assign slice */ 687 /* Assign slice */
687 Py_ssize_t i; 688 Py_ssize_t cur, i;
688 size_t cur;
689 689
690 if (needed != slicelen) { 690 if (needed != slicelen) {
691 PyErr_Format(PyExc_ValueError, 691 PyErr_Format(PyExc_ValueError,
692 "attempt to assign bytes of size %zd " 692 "attempt to assign bytes of size %zd "
693 "to extended slice of size %zd", 693 "to extended slice of size %zd",
694 needed, slicelen); 694 needed, slicelen);
695 return -1; 695 return -1;
696 } 696 }
697 for (cur = start, i = 0; i < slicelen; cur += step, i++) 697 for (cur = start, i = 0; i < slicelen; cur += step, i++)
698 self->ob_bytes[cur] = bytes[i]; 698 self->ob_bytes[cur] = bytes[i];
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 PyMem_Free(self->ob_bytes); 1031 PyMem_Free(self->ob_bytes);
1032 } 1032 }
1033 Py_TYPE(self)->tp_free((PyObject *)self); 1033 Py_TYPE(self)->tp_free((PyObject *)self);
1034 } 1034 }
1035 1035
1036 1036
1037 /* -------------------------------------------------------------------- */ 1037 /* -------------------------------------------------------------------- */
1038 /* Methods */ 1038 /* Methods */
1039 1039
1040 #define STRINGLIB_CHAR char 1040 #define STRINGLIB_CHAR char
1041 #define STRINGLIB_CMP memcmp
1041 #define STRINGLIB_LEN PyByteArray_GET_SIZE 1042 #define STRINGLIB_LEN PyByteArray_GET_SIZE
1042 #define STRINGLIB_STR PyByteArray_AS_STRING 1043 #define STRINGLIB_STR PyByteArray_AS_STRING
1043 #define STRINGLIB_NEW PyByteArray_FromStringAndSize 1044 #define STRINGLIB_NEW PyByteArray_FromStringAndSize
1044 #define STRINGLIB_ISSPACE Py_ISSPACE 1045 #define STRINGLIB_EMPTY nullbytes
1045 #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
1046 #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact 1046 #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1047 #define STRINGLIB_MUTABLE 1 1047 #define STRINGLIB_MUTABLE 1
1048 #define FROM_BYTEARRAY 1
1048 1049
1049 #include "stringlib/fastsearch.h" 1050 #include "stringlib/fastsearch.h"
1050 #include "stringlib/count.h" 1051 #include "stringlib/count.h"
1051 #include "stringlib/find.h" 1052 #include "stringlib/find.h"
1052 #include "stringlib/partition.h" 1053 #include "stringlib/partition.h"
1053 #include "stringlib/split.h"
1054 #include "stringlib/ctype.h" 1054 #include "stringlib/ctype.h"
1055 #include "stringlib/transmogrify.h" 1055 #include "stringlib/transmogrify.h"
1056 1056
1057 1057
1058 /* The following Py_LOCAL_INLINE and Py_LOCAL functions 1058 /* The following Py_LOCAL_INLINE and Py_LOCAL functions
1059 were copied from the old char* style string object. */ 1059 were copied from the old char* style string object. */
1060 1060
1061 /* helper macro to fixup start/end slice values */ 1061 Py_LOCAL_INLINE(void)
1062 #define ADJUST_INDICES(start, end, len) \ 1062 _adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len)
1063 if (end > len) \ 1063 {
1064 end = len; \ 1064 if (*end > len)
1065 else if (end < 0) { \ 1065 *end = len;
1066 end += len; \ 1066 else if (*end < 0)
1067 if (end < 0) \ 1067 *end += len;
1068 end = 0; \ 1068 if (*end < 0)
1069 } \ 1069 *end = 0;
1070 if (start < 0) { \ 1070 if (*start < 0)
1071 start += len; \ 1071 *start += len;
1072 if (start < 0) \ 1072 if (*start < 0)
1073 start = 0; \ 1073 *start = 0;
1074 } 1074 }
1075
1075 1076
1076 Py_LOCAL_INLINE(Py_ssize_t) 1077 Py_LOCAL_INLINE(Py_ssize_t)
1077 bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir) 1078 bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
1078 { 1079 {
1079 PyObject *subobj; 1080 PyObject *subobj;
1080 Py_buffer subbuf; 1081 Py_buffer subbuf;
1081 Py_ssize_t start=0, end=PY_SSIZE_T_MAX; 1082 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1082 Py_ssize_t res; 1083 Py_ssize_t res;
1083 1084
1084 if (!stringlib_parse_tuple_finds("find/rfind/index/rindex", args, &subobj, 1085 if (!stringlib_parse_args_finds("find/rfind/index/rindex",
1085 &start, &end, 0)) 1086 args, &subobj, &start, &end))
1086 return -2; 1087 return -2;
1087
1088 if (_getbuffer(subobj, &subbuf) < 0) 1088 if (_getbuffer(subobj, &subbuf) < 0)
1089 return -2; 1089 return -2;
1090 if (dir > 0) 1090 if (dir > 0)
1091 res = stringlib_find_slice( 1091 res = stringlib_find_slice(
1092 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), 1092 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1093 subbuf.buf, subbuf.len, start, end); 1093 subbuf.buf, subbuf.len, start, end);
1094 else 1094 else
1095 res = stringlib_rfind_slice( 1095 res = stringlib_rfind_slice(
1096 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), 1096 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1097 subbuf.buf, subbuf.len, start, end); 1097 subbuf.buf, subbuf.len, start, end);
(...skipping 28 matching lines...) Expand all
1126 1126
1127 static PyObject * 1127 static PyObject *
1128 bytearray_count(PyByteArrayObject *self, PyObject *args) 1128 bytearray_count(PyByteArrayObject *self, PyObject *args)
1129 { 1129 {
1130 PyObject *sub_obj; 1130 PyObject *sub_obj;
1131 const char *str = PyByteArray_AS_STRING(self); 1131 const char *str = PyByteArray_AS_STRING(self);
1132 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; 1132 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1133 Py_buffer vsub; 1133 Py_buffer vsub;
1134 PyObject *count_obj; 1134 PyObject *count_obj;
1135 1135
1136 if (!stringlib_parse_tuple_finds("count", args, &sub_obj, &start, &end, 0)) 1136 if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
1137 return NULL; 1137 return NULL;
1138 1138
1139 if (_getbuffer(sub_obj, &vsub) < 0) 1139 if (_getbuffer(sub_obj, &vsub) < 0)
1140 return NULL; 1140 return NULL;
1141 1141
1142 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self)); 1142 _adjust_indices(&start, &end, PyByteArray_GET_SIZE(self));
1143 1143
1144 count_obj = PyLong_FromSsize_t( 1144 count_obj = PyLong_FromSsize_t(
1145 stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T _MAX) 1145 stringlib_count(str + start, end - start, vsub.buf, vsub.len)
1146 ); 1146 );
1147 PyBuffer_Release(&vsub); 1147 PyBuffer_Release(&vsub);
1148 return count_obj; 1148 return count_obj;
1149 } 1149 }
1150 1150
1151 PyDoc_STRVAR(clear__doc__,
1152 "B.clear() -> None\n\
1153 \n\
1154 Remove all items from B.");
1155
1156 static PyObject *
1157 bytearray_clear(PyByteArrayObject *self)
1158 {
1159 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1160 return NULL;
1161 Py_RETURN_NONE;
1162 }
1163
1164 PyDoc_STRVAR(copy__doc__,
1165 "B.copy() -> bytearray\n\
1166 \n\
1167 Return a copy of B.");
1168
1169 static PyObject *
1170 bytearray_copy(PyByteArrayObject *self)
1171 {
1172 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self) ,
1173 PyByteArray_GET_SIZE(self));
1174 }
1175 1151
1176 PyDoc_STRVAR(index__doc__, 1152 PyDoc_STRVAR(index__doc__,
1177 "B.index(sub[, start[, end]]) -> int\n\ 1153 "B.index(sub[, start[, end]]) -> int\n\
1178 \n\ 1154 \n\
1179 Like B.find() but raise ValueError when the subsection is not found."); 1155 Like B.find() but raise ValueError when the subsection is not found.");
1180 1156
1181 static PyObject * 1157 static PyObject *
1182 bytearray_index(PyByteArrayObject *self, PyObject *args) 1158 bytearray_index(PyByteArrayObject *self, PyObject *args)
1183 { 1159 {
1184 Py_ssize_t result = bytearray_find_internal(self, args, +1); 1160 Py_ssize_t result = bytearray_find_internal(self, args, +1);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 Py_ssize_t len = PyByteArray_GET_SIZE(self); 1243 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1268 const char* str; 1244 const char* str;
1269 Py_buffer vsubstr; 1245 Py_buffer vsubstr;
1270 int rv = 0; 1246 int rv = 0;
1271 1247
1272 str = PyByteArray_AS_STRING(self); 1248 str = PyByteArray_AS_STRING(self);
1273 1249
1274 if (_getbuffer(substr, &vsubstr) < 0) 1250 if (_getbuffer(substr, &vsubstr) < 0)
1275 return -1; 1251 return -1;
1276 1252
1277 ADJUST_INDICES(start, end, len); 1253 _adjust_indices(&start, &end, len);
1278 1254
1279 if (direction < 0) { 1255 if (direction < 0) {
1280 /* startswith */ 1256 /* startswith */
1281 if (start+vsubstr.len > len) { 1257 if (start+vsubstr.len > len) {
1282 goto done; 1258 goto done;
1283 } 1259 }
1284 } else { 1260 } else {
1285 /* endswith */ 1261 /* endswith */
1286 if (end-start < vsubstr.len || start > len) { 1262 if (end-start < vsubstr.len || start > len) {
1287 goto done; 1263 goto done;
(...skipping 20 matching lines...) Expand all
1308 prefix can also be a tuple of strings to try."); 1284 prefix can also be a tuple of strings to try.");
1309 1285
1310 static PyObject * 1286 static PyObject *
1311 bytearray_startswith(PyByteArrayObject *self, PyObject *args) 1287 bytearray_startswith(PyByteArrayObject *self, PyObject *args)
1312 { 1288 {
1313 Py_ssize_t start = 0; 1289 Py_ssize_t start = 0;
1314 Py_ssize_t end = PY_SSIZE_T_MAX; 1290 Py_ssize_t end = PY_SSIZE_T_MAX;
1315 PyObject *subobj; 1291 PyObject *subobj;
1316 int result; 1292 int result;
1317 1293
1318 if (!stringlib_parse_tuple_finds("startswith", args, &subobj, 1294 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
1319 &start, &end, 0)) 1295 return NULL;
1320 return NULL;
1321
1322 if (PyTuple_Check(subobj)) { 1296 if (PyTuple_Check(subobj)) {
1323 Py_ssize_t i; 1297 Py_ssize_t i;
1324 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { 1298 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
1325 result = _bytearray_tailmatch(self, 1299 result = _bytearray_tailmatch(self,
1326 PyTuple_GET_ITEM(subobj, i), 1300 PyTuple_GET_ITEM(subobj, i),
1327 start, end, -1); 1301 start, end, -1);
1328 if (result == -1) 1302 if (result == -1)
1329 return NULL; 1303 return NULL;
1330 else if (result) { 1304 else if (result) {
1331 Py_RETURN_TRUE; 1305 Py_RETURN_TRUE;
(...skipping 17 matching lines...) Expand all
1349 suffix can also be a tuple of strings to try."); 1323 suffix can also be a tuple of strings to try.");
1350 1324
1351 static PyObject * 1325 static PyObject *
1352 bytearray_endswith(PyByteArrayObject *self, PyObject *args) 1326 bytearray_endswith(PyByteArrayObject *self, PyObject *args)
1353 { 1327 {
1354 Py_ssize_t start = 0; 1328 Py_ssize_t start = 0;
1355 Py_ssize_t end = PY_SSIZE_T_MAX; 1329 Py_ssize_t end = PY_SSIZE_T_MAX;
1356 PyObject *subobj; 1330 PyObject *subobj;
1357 int result; 1331 int result;
1358 1332
1359 if (!stringlib_parse_tuple_finds("endswith", args, &subobj, 1333 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
1360 &start, &end, 0)) 1334 return NULL;
1361 return NULL;
1362
1363 if (PyTuple_Check(subobj)) { 1335 if (PyTuple_Check(subobj)) {
1364 Py_ssize_t i; 1336 Py_ssize_t i;
1365 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { 1337 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
1366 result = _bytearray_tailmatch(self, 1338 result = _bytearray_tailmatch(self,
1367 PyTuple_GET_ITEM(subobj, i), 1339 PyTuple_GET_ITEM(subobj, i),
1368 start, end, +1); 1340 start, end, +1);
1369 if (result == -1) 1341 if (result == -1)
1370 return NULL; 1342 return NULL;
1371 else if (result) { 1343 else if (result) {
1372 Py_RETURN_TRUE; 1344 Py_RETURN_TRUE;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 } 1453 }
1482 1454
1483 1455
1484 static PyObject * 1456 static PyObject *
1485 bytearray_maketrans(PyObject *null, PyObject *args) 1457 bytearray_maketrans(PyObject *null, PyObject *args)
1486 { 1458 {
1487 return _Py_bytes_maketrans(args); 1459 return _Py_bytes_maketrans(args);
1488 } 1460 }
1489 1461
1490 1462
1463 #define FORWARD 1
1464 #define REVERSE -1
1465
1491 /* find and count characters and substrings */ 1466 /* find and count characters and substrings */
1492 1467
1493 #define findchar(target, target_len, c) \ 1468 #define findchar(target, target_len, c) \
1494 ((char *)memchr((const void *)(target), c, target_len)) 1469 ((char *)memchr((const void *)(target), c, target_len))
1470
1471 /* Don't call if length < 2 */
1472 #define Py_STRING_MATCH(target, offset, pattern, length) \
1473 (target[offset] == pattern[0] && \
1474 target[offset+length-1] == pattern[length-1] && \
1475 !memcmp(target+offset+1, pattern+1, length-2) )
1495 1476
1496 1477
1497 /* Bytes ops must return a string, create a copy */ 1478 /* Bytes ops must return a string, create a copy */
1498 Py_LOCAL(PyByteArrayObject *) 1479 Py_LOCAL(PyByteArrayObject *)
1499 return_self(PyByteArrayObject *self) 1480 return_self(PyByteArrayObject *self)
1500 { 1481 {
1501 /* always return a new bytearray */ 1482 /* always return a new bytearray */
1502 return (PyByteArrayObject *)PyByteArray_FromStringAndSize( 1483 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1503 PyByteArray_AS_STRING(self), 1484 PyByteArray_AS_STRING(self),
1504 PyByteArray_GET_SIZE(self)); 1485 PyByteArray_GET_SIZE(self));
1505 } 1486 }
1506 1487
1507 Py_LOCAL_INLINE(Py_ssize_t) 1488 Py_LOCAL_INLINE(Py_ssize_t)
1508 countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount ) 1489 countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount )
1509 { 1490 {
1510 Py_ssize_t count=0; 1491 Py_ssize_t count=0;
1511 const char *start=target; 1492 const char *start=target;
1512 const char *end=target+target_len; 1493 const char *end=target+target_len;
1513 1494
1514 while ( (start=findchar(start, end-start, c)) != NULL ) { 1495 while ( (start=findchar(start, end-start, c)) != NULL ) {
1515 count++; 1496 count++;
1516 if (count >= maxcount) 1497 if (count >= maxcount)
1517 break; 1498 break;
1518 start += 1; 1499 start += 1;
1519 } 1500 }
1520 return count; 1501 return count;
1521 } 1502 }
1522 1503
1504 Py_LOCAL(Py_ssize_t)
1505 findstring(const char *target, Py_ssize_t target_len,
1506 const char *pattern, Py_ssize_t pattern_len,
1507 Py_ssize_t start,
1508 Py_ssize_t end,
1509 int direction)
1510 {
1511 if (start < 0) {
1512 start += target_len;
1513 if (start < 0)
1514 start = 0;
1515 }
1516 if (end > target_len) {
1517 end = target_len;
1518 } else if (end < 0) {
1519 end += target_len;
1520 if (end < 0)
1521 end = 0;
1522 }
1523
1524 /* zero-length substrings always match at the first attempt */
1525 if (pattern_len == 0)
1526 return (direction > 0) ? start : end;
1527
1528 end -= pattern_len;
1529
1530 if (direction < 0) {
1531 for (; end >= start; end--)
1532 if (Py_STRING_MATCH(target, end, pattern, pattern_len))
1533 return end;
1534 } else {
1535 for (; start <= end; start++)
1536 if (Py_STRING_MATCH(target, start, pattern, pattern_len))
1537 return start;
1538 }
1539 return -1;
1540 }
1541
1542 Py_LOCAL_INLINE(Py_ssize_t)
1543 countstring(const char *target, Py_ssize_t target_len,
1544 const char *pattern, Py_ssize_t pattern_len,
1545 Py_ssize_t start,
1546 Py_ssize_t end,
1547 int direction, Py_ssize_t maxcount)
1548 {
1549 Py_ssize_t count=0;
1550
1551 if (start < 0) {
1552 start += target_len;
1553 if (start < 0)
1554 start = 0;
1555 }
1556 if (end > target_len) {
1557 end = target_len;
1558 } else if (end < 0) {
1559 end += target_len;
1560 if (end < 0)
1561 end = 0;
1562 }
1563
1564 /* zero-length substrings match everywhere */
1565 if (pattern_len == 0 || maxcount == 0) {
1566 if (target_len+1 < maxcount)
1567 return target_len+1;
1568 return maxcount;
1569 }
1570
1571 end -= pattern_len;
1572 if (direction < 0) {
1573 for (; (end >= start); end--)
1574 if (Py_STRING_MATCH(target, end, pattern, pattern_len)) {
1575 count++;
1576 if (--maxcount <= 0) break;
1577 end -= pattern_len-1;
1578 }
1579 } else {
1580 for (; (start <= end); start++)
1581 if (Py_STRING_MATCH(target, start, pattern, pattern_len)) {
1582 count++;
1583 if (--maxcount <= 0)
1584 break;
1585 start += pattern_len-1;
1586 }
1587 }
1588 return count;
1589 }
1590
1523 1591
1524 /* Algorithms for different cases of string replacement */ 1592 /* Algorithms for different cases of string replacement */
1525 1593
1526 /* len(self)>=1, from="", len(to)>=1, maxcount>=1 */ 1594 /* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1527 Py_LOCAL(PyByteArrayObject *) 1595 Py_LOCAL(PyByteArrayObject *)
1528 replace_interleave(PyByteArrayObject *self, 1596 replace_interleave(PyByteArrayObject *self,
1529 const char *to_s, Py_ssize_t to_len, 1597 const char *to_s, Py_ssize_t to_len,
1530 Py_ssize_t maxcount) 1598 Py_ssize_t maxcount)
1531 { 1599 {
1532 char *self_s, *result_s; 1600 char *self_s, *result_s;
1533 Py_ssize_t self_len, result_len; 1601 Py_ssize_t self_len, result_len;
1534 Py_ssize_t count, i; 1602 Py_ssize_t count, i, product;
1535 PyByteArrayObject *result; 1603 PyByteArrayObject *result;
1536 1604
1537 self_len = PyByteArray_GET_SIZE(self); 1605 self_len = PyByteArray_GET_SIZE(self);
1538 1606
1539 /* 1 at the end plus 1 after every character; 1607 /* 1 at the end plus 1 after every character */
1540 count = min(maxcount, self_len + 1) */ 1608 count = self_len+1;
1541 if (maxcount <= self_len) 1609 if (maxcount < count)
1542 count = maxcount; 1610 count = maxcount;
1543 else
1544 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1545 count = self_len + 1;
1546 1611
1547 /* Check for overflow */ 1612 /* Check for overflow */
1548 /* result_len = count * to_len + self_len; */ 1613 /* result_len = count * to_len + self_len; */
1549 assert(count > 0); 1614 product = count * to_len;
1550 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) { 1615 if (product / to_len != count) {
1551 PyErr_SetString(PyExc_OverflowError, 1616 PyErr_SetString(PyExc_OverflowError,
1552 "replace string is too long"); 1617 "replace string is too long");
1553 return NULL; 1618 return NULL;
1554 } 1619 }
1555 result_len = count * to_len + self_len; 1620 result_len = product + self_len;
1621 if (result_len < 0) {
1622 PyErr_SetString(PyExc_OverflowError,
1623 "replace string is too long");
1624 return NULL;
1625 }
1556 1626
1557 if (! (result = (PyByteArrayObject *) 1627 if (! (result = (PyByteArrayObject *)
1558 PyByteArray_FromStringAndSize(NULL, result_len)) ) 1628 PyByteArray_FromStringAndSize(NULL, result_len)) )
1559 return NULL; 1629 return NULL;
1560 1630
1561 self_s = PyByteArray_AS_STRING(self); 1631 self_s = PyByteArray_AS_STRING(self);
1562 result_s = PyByteArray_AS_STRING(result); 1632 result_s = PyByteArray_AS_STRING(result);
1563 1633
1564 /* TODO: special case single character, which doesn't need memcpy */ 1634 /* TODO: special case single character, which doesn't need memcpy */
1565 1635
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1632 { 1702 {
1633 char *self_s, *result_s; 1703 char *self_s, *result_s;
1634 char *start, *next, *end; 1704 char *start, *next, *end;
1635 Py_ssize_t self_len, result_len; 1705 Py_ssize_t self_len, result_len;
1636 Py_ssize_t count, offset; 1706 Py_ssize_t count, offset;
1637 PyByteArrayObject *result; 1707 PyByteArrayObject *result;
1638 1708
1639 self_len = PyByteArray_GET_SIZE(self); 1709 self_len = PyByteArray_GET_SIZE(self);
1640 self_s = PyByteArray_AS_STRING(self); 1710 self_s = PyByteArray_AS_STRING(self);
1641 1711
1642 count = stringlib_count(self_s, self_len, 1712 count = countstring(self_s, self_len,
1643 from_s, from_len, 1713 from_s, from_len,
1644 maxcount); 1714 0, self_len, 1,
1715 maxcount);
1645 1716
1646 if (count == 0) { 1717 if (count == 0) {
1647 /* no matches */ 1718 /* no matches */
1648 return return_self(self); 1719 return return_self(self);
1649 } 1720 }
1650 1721
1651 result_len = self_len - (count * from_len); 1722 result_len = self_len - (count * from_len);
1652 assert (result_len>=0); 1723 assert (result_len>=0);
1653 1724
1654 if ( (result = (PyByteArrayObject *) 1725 if ( (result = (PyByteArrayObject *)
1655 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL ) 1726 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1656 return NULL; 1727 return NULL;
1657 1728
1658 result_s = PyByteArray_AS_STRING(result); 1729 result_s = PyByteArray_AS_STRING(result);
1659 1730
1660 start = self_s; 1731 start = self_s;
1661 end = self_s + self_len; 1732 end = self_s + self_len;
1662 while (count-- > 0) { 1733 while (count-- > 0) {
1663 offset = stringlib_find(start, end-start, 1734 offset = findstring(start, end-start,
1664 from_s, from_len, 1735 from_s, from_len,
1665 0); 1736 0, end-start, FORWARD);
1666 if (offset == -1) 1737 if (offset == -1)
1667 break; 1738 break;
1668 next = start + offset; 1739 next = start + offset;
1669 1740
1670 Py_MEMCPY(result_s, start, next-start); 1741 Py_MEMCPY(result_s, start, next-start);
1671 1742
1672 result_s += (next-start); 1743 result_s += (next-start);
1673 start = next+from_len; 1744 start = next+from_len;
1674 } 1745 }
1675 Py_MEMCPY(result_s, start, end-start); 1746 Py_MEMCPY(result_s, start, end-start);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1731 char *result_s, *start, *end; 1802 char *result_s, *start, *end;
1732 char *self_s; 1803 char *self_s;
1733 Py_ssize_t self_len, offset; 1804 Py_ssize_t self_len, offset;
1734 PyByteArrayObject *result; 1805 PyByteArrayObject *result;
1735 1806
1736 /* The result bytes will be the same size */ 1807 /* The result bytes will be the same size */
1737 1808
1738 self_s = PyByteArray_AS_STRING(self); 1809 self_s = PyByteArray_AS_STRING(self);
1739 self_len = PyByteArray_GET_SIZE(self); 1810 self_len = PyByteArray_GET_SIZE(self);
1740 1811
1741 offset = stringlib_find(self_s, self_len, 1812 offset = findstring(self_s, self_len,
1742 from_s, from_len, 1813 from_s, from_len,
1743 0); 1814 0, self_len, FORWARD);
1744 if (offset == -1) { 1815 if (offset == -1) {
1745 /* No matches; return the original bytes */ 1816 /* No matches; return the original bytes */
1746 return return_self(self); 1817 return return_self(self);
1747 } 1818 }
1748 1819
1749 /* Need to make a new bytes */ 1820 /* Need to make a new bytes */
1750 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len) ; 1821 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len) ;
1751 if (result == NULL) 1822 if (result == NULL)
1752 return NULL; 1823 return NULL;
1753 result_s = PyByteArray_AS_STRING(result); 1824 result_s = PyByteArray_AS_STRING(result);
1754 Py_MEMCPY(result_s, self_s, self_len); 1825 Py_MEMCPY(result_s, self_s, self_len);
1755 1826
1756 /* change everything in-place, starting with this one */ 1827 /* change everything in-place, starting with this one */
1757 start = result_s + offset; 1828 start = result_s + offset;
1758 Py_MEMCPY(start, to_s, from_len); 1829 Py_MEMCPY(start, to_s, from_len);
1759 start += from_len; 1830 start += from_len;
1760 end = result_s + self_len; 1831 end = result_s + self_len;
1761 1832
1762 while ( --maxcount > 0) { 1833 while ( --maxcount > 0) {
1763 offset = stringlib_find(start, end-start, 1834 offset = findstring(start, end-start,
1764 from_s, from_len, 1835 from_s, from_len,
1765 0); 1836 0, end-start, FORWARD);
1766 if (offset==-1) 1837 if (offset==-1)
1767 break; 1838 break;
1768 Py_MEMCPY(start+offset, to_s, from_len); 1839 Py_MEMCPY(start+offset, to_s, from_len);
1769 start += offset+from_len; 1840 start += offset+from_len;
1770 } 1841 }
1771 1842
1772 return result; 1843 return result;
1773 } 1844 }
1774 1845
1775 /* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */ 1846 /* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1776 Py_LOCAL(PyByteArrayObject *) 1847 Py_LOCAL(PyByteArrayObject *)
1777 replace_single_character(PyByteArrayObject *self, 1848 replace_single_character(PyByteArrayObject *self,
1778 char from_c, 1849 char from_c,
1779 const char *to_s, Py_ssize_t to_len, 1850 const char *to_s, Py_ssize_t to_len,
1780 Py_ssize_t maxcount) 1851 Py_ssize_t maxcount)
1781 { 1852 {
1782 char *self_s, *result_s; 1853 char *self_s, *result_s;
1783 char *start, *next, *end; 1854 char *start, *next, *end;
1784 Py_ssize_t self_len, result_len; 1855 Py_ssize_t self_len, result_len;
1785 Py_ssize_t count; 1856 Py_ssize_t count, product;
1786 PyByteArrayObject *result; 1857 PyByteArrayObject *result;
1787 1858
1788 self_s = PyByteArray_AS_STRING(self); 1859 self_s = PyByteArray_AS_STRING(self);
1789 self_len = PyByteArray_GET_SIZE(self); 1860 self_len = PyByteArray_GET_SIZE(self);
1790 1861
1791 count = countchar(self_s, self_len, from_c, maxcount); 1862 count = countchar(self_s, self_len, from_c, maxcount);
1792 if (count == 0) { 1863 if (count == 0) {
1793 /* no matches, return unchanged */ 1864 /* no matches, return unchanged */
1794 return return_self(self); 1865 return return_self(self);
1795 } 1866 }
1796 1867
1797 /* use the difference between current and new, hence the "-1" */ 1868 /* use the difference between current and new, hence the "-1" */
1798 /* result_len = self_len + count * (to_len-1) */ 1869 /* result_len = self_len + count * (to_len-1) */
1799 assert(count > 0); 1870 product = count * (to_len-1);
1800 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) { 1871 if (product / (to_len-1) != count) {
1801 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); 1872 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1802 return NULL; 1873 return NULL;
1803 } 1874 }
1804 result_len = self_len + count * (to_len - 1); 1875 result_len = self_len + product;
1876 if (result_len < 0) {
1877 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1878 return NULL;
1879 }
1805 1880
1806 if ( (result = (PyByteArrayObject *) 1881 if ( (result = (PyByteArrayObject *)
1807 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) 1882 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1808 return NULL; 1883 return NULL;
1809 result_s = PyByteArray_AS_STRING(result); 1884 result_s = PyByteArray_AS_STRING(result);
1810 1885
1811 start = self_s; 1886 start = self_s;
1812 end = self_s + self_len; 1887 end = self_s + self_len;
1813 while (count-- > 0) { 1888 while (count-- > 0) {
1814 next = findchar(start, end-start, from_c); 1889 next = findchar(start, end-start, from_c);
(...skipping 23 matching lines...) Expand all
1838 /* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */ 1913 /* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1839 Py_LOCAL(PyByteArrayObject *) 1914 Py_LOCAL(PyByteArrayObject *)
1840 replace_substring(PyByteArrayObject *self, 1915 replace_substring(PyByteArrayObject *self,
1841 const char *from_s, Py_ssize_t from_len, 1916 const char *from_s, Py_ssize_t from_len,
1842 const char *to_s, Py_ssize_t to_len, 1917 const char *to_s, Py_ssize_t to_len,
1843 Py_ssize_t maxcount) 1918 Py_ssize_t maxcount)
1844 { 1919 {
1845 char *self_s, *result_s; 1920 char *self_s, *result_s;
1846 char *start, *next, *end; 1921 char *start, *next, *end;
1847 Py_ssize_t self_len, result_len; 1922 Py_ssize_t self_len, result_len;
1848 Py_ssize_t count, offset; 1923 Py_ssize_t count, offset, product;
1849 PyByteArrayObject *result; 1924 PyByteArrayObject *result;
1850 1925
1851 self_s = PyByteArray_AS_STRING(self); 1926 self_s = PyByteArray_AS_STRING(self);
1852 self_len = PyByteArray_GET_SIZE(self); 1927 self_len = PyByteArray_GET_SIZE(self);
1853 1928
1854 count = stringlib_count(self_s, self_len, 1929 count = countstring(self_s, self_len,
1855 from_s, from_len, 1930 from_s, from_len,
1856 maxcount); 1931 0, self_len, FORWARD, maxcount);
1857
1858 if (count == 0) { 1932 if (count == 0) {
1859 /* no matches, return unchanged */ 1933 /* no matches, return unchanged */
1860 return return_self(self); 1934 return return_self(self);
1861 } 1935 }
1862 1936
1863 /* Check for overflow */ 1937 /* Check for overflow */
1864 /* result_len = self_len + count * (to_len-from_len) */ 1938 /* result_len = self_len + count * (to_len-from_len) */
1865 assert(count > 0); 1939 product = count * (to_len-from_len);
1866 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) { 1940 if (product / (to_len-from_len) != count) {
1867 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); 1941 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1868 return NULL; 1942 return NULL;
1869 } 1943 }
1870 result_len = self_len + count * (to_len - from_len); 1944 result_len = self_len + product;
1945 if (result_len < 0) {
1946 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1947 return NULL;
1948 }
1871 1949
1872 if ( (result = (PyByteArrayObject *) 1950 if ( (result = (PyByteArrayObject *)
1873 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) 1951 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1874 return NULL; 1952 return NULL;
1875 result_s = PyByteArray_AS_STRING(result); 1953 result_s = PyByteArray_AS_STRING(result);
1876 1954
1877 start = self_s; 1955 start = self_s;
1878 end = self_s + self_len; 1956 end = self_s + self_len;
1879 while (count-- > 0) { 1957 while (count-- > 0) {
1880 offset = stringlib_find(start, end-start, 1958 offset = findstring(start, end-start,
1881 from_s, from_len, 1959 from_s, from_len,
1882 0); 1960 0, end-start, FORWARD);
1883 if (offset == -1) 1961 if (offset == -1)
1884 break; 1962 break;
1885 next = start+offset; 1963 next = start+offset;
1886 if (next == start) { 1964 if (next == start) {
1887 /* replace with the 'to' */ 1965 /* replace with the 'to' */
1888 Py_MEMCPY(result_s, to_s, to_len); 1966 Py_MEMCPY(result_s, to_s, to_len);
1889 result_s += to_len; 1967 result_s += to_len;
1890 start += from_len; 1968 start += from_len;
1891 } else { 1969 } else {
1892 /* copy the unchanged old then the 'to' */ 1970 /* copy the unchanged old then the 'to' */
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 2079
2002 res = (PyObject *)replace((PyByteArrayObject *) self, 2080 res = (PyObject *)replace((PyByteArrayObject *) self,
2003 vfrom.buf, vfrom.len, 2081 vfrom.buf, vfrom.len,
2004 vto.buf, vto.len, count); 2082 vto.buf, vto.len, count);
2005 2083
2006 PyBuffer_Release(&vfrom); 2084 PyBuffer_Release(&vfrom);
2007 PyBuffer_Release(&vto); 2085 PyBuffer_Release(&vto);
2008 return res; 2086 return res;
2009 } 2087 }
2010 2088
2089
2090 /* Overallocate the initial list to reduce the number of reallocs for small
2091 split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three
2092 resizes, to sizes 4, 8, then 16. Most observed string splits are for human
2093 text (roughly 11 words per line) and field delimited data (usually 1-10
2094 fields). For large strings the split algorithms are bandwidth limited
2095 so increasing the preallocation likely will not improve things.*/
2096
2097 #define MAX_PREALLOC 12
2098
2099 /* 5 splits gives 6 elements */
2100 #define PREALLOC_SIZE(maxsplit) \
2101 (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
2102
2103 #define SPLIT_APPEND(data, left, right) \
2104 str = PyByteArray_FromStringAndSize((data) + (left), \
2105 (right) - (left)); \
2106 if (str == NULL) \
2107 goto onError; \
2108 if (PyList_Append(list, str)) { \
2109 Py_DECREF(str); \
2110 goto onError; \
2111 } \
2112 else \
2113 Py_DECREF(str);
2114
2115 #define SPLIT_ADD(data, left, right) { \
2116 str = PyByteArray_FromStringAndSize((data) + (left), \
2117 (right) - (left)); \
2118 if (str == NULL) \
2119 goto onError; \
2120 if (count < MAX_PREALLOC) { \
2121 PyList_SET_ITEM(list, count, str); \
2122 } else { \
2123 if (PyList_Append(list, str)) { \
2124 Py_DECREF(str); \
2125 goto onError; \
2126 } \
2127 else \
2128 Py_DECREF(str); \
2129 } \
2130 count++; }
2131
2132 /* Always force the list to the expected size. */
2133 #define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
2134
2135
2136 Py_LOCAL_INLINE(PyObject *)
2137 split_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
2138 {
2139 register Py_ssize_t i, j, count = 0;
2140 PyObject *str;
2141 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2142
2143 if (list == NULL)
2144 return NULL;
2145
2146 i = j = 0;
2147 while ((j < len) && (maxcount-- > 0)) {
2148 for(; j < len; j++) {
2149 /* I found that using memchr makes no difference */
2150 if (s[j] == ch) {
2151 SPLIT_ADD(s, i, j);
2152 i = j = j + 1;
2153 break;
2154 }
2155 }
2156 }
2157 if (i <= len) {
2158 SPLIT_ADD(s, i, len);
2159 }
2160 FIX_PREALLOC_SIZE(list);
2161 return list;
2162
2163 onError:
2164 Py_DECREF(list);
2165 return NULL;
2166 }
2167
2168
2169 Py_LOCAL_INLINE(PyObject *)
2170 split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
2171 {
2172 register Py_ssize_t i, j, count = 0;
2173 PyObject *str;
2174 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2175
2176 if (list == NULL)
2177 return NULL;
2178
2179 for (i = j = 0; i < len; ) {
2180 /* find a token */
2181 while (i < len && Py_ISSPACE(s[i]))
2182 i++;
2183 j = i;
2184 while (i < len && !Py_ISSPACE(s[i]))
2185 i++;
2186 if (j < i) {
2187 if (maxcount-- <= 0)
2188 break;
2189 SPLIT_ADD(s, j, i);
2190 while (i < len && Py_ISSPACE(s[i]))
2191 i++;
2192 j = i;
2193 }
2194 }
2195 if (j < len) {
2196 SPLIT_ADD(s, j, len);
2197 }
2198 FIX_PREALLOC_SIZE(list);
2199 return list;
2200
2201 onError:
2202 Py_DECREF(list);
2203 return NULL;
2204 }
2205
2011 PyDoc_STRVAR(split__doc__, 2206 PyDoc_STRVAR(split__doc__,
2012 "B.split([sep[, maxsplit]]) -> list of bytearrays\n\ 2207 "B.split([sep[, maxsplit]]) -> list of bytearrays\n\
2013 \n\ 2208 \n\
2014 Return a list of the sections in B, using sep as the delimiter.\n\ 2209 Return a list of the sections in B, using sep as the delimiter.\n\
2015 If sep is not given, B is split on ASCII whitespace characters\n\ 2210 If sep is not given, B is split on ASCII whitespace characters\n\
2016 (space, tab, return, newline, formfeed, vertical tab).\n\ 2211 (space, tab, return, newline, formfeed, vertical tab).\n\
2017 If maxsplit is given, at most maxsplit splits are done."); 2212 If maxsplit is given, at most maxsplit splits are done.");
2018 2213
2019 static PyObject * 2214 static PyObject *
2020 bytearray_split(PyByteArrayObject *self, PyObject *args) 2215 bytearray_split(PyByteArrayObject *self, PyObject *args)
2021 { 2216 {
2022 Py_ssize_t len = PyByteArray_GET_SIZE(self), n; 2217 Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
2023 Py_ssize_t maxsplit = -1; 2218 Py_ssize_t maxsplit = -1, count = 0;
2024 const char *s = PyByteArray_AS_STRING(self), *sub; 2219 const char *s = PyByteArray_AS_STRING(self), *sub;
2025 PyObject *list, *subobj = Py_None; 2220 PyObject *list, *str, *subobj = Py_None;
2026 Py_buffer vsub; 2221 Py_buffer vsub;
2222 #ifdef USE_FAST
2223 Py_ssize_t pos;
2224 #endif
2027 2225
2028 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit)) 2226 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2029 return NULL; 2227 return NULL;
2030 if (maxsplit < 0) 2228 if (maxsplit < 0)
2031 maxsplit = PY_SSIZE_T_MAX; 2229 maxsplit = PY_SSIZE_T_MAX;
2032 2230
2033 if (subobj == Py_None) 2231 if (subobj == Py_None)
2034 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); 2232 return split_whitespace(s, len, maxsplit);
2035 2233
2036 if (_getbuffer(subobj, &vsub) < 0) 2234 if (_getbuffer(subobj, &vsub) < 0)
2037 return NULL; 2235 return NULL;
2038 sub = vsub.buf; 2236 sub = vsub.buf;
2039 n = vsub.len; 2237 n = vsub.len;
2040 2238
2041 list = stringlib_split( 2239 if (n == 0) {
2042 (PyObject*) self, s, len, sub, n, maxsplit 2240 PyErr_SetString(PyExc_ValueError, "empty separator");
2043 ); 2241 PyBuffer_Release(&vsub);
2242 return NULL;
2243 }
2244 if (n == 1) {
2245 list = split_char(s, len, sub[0], maxsplit);
2246 PyBuffer_Release(&vsub);
2247 return list;
2248 }
2249
2250 list = PyList_New(PREALLOC_SIZE(maxsplit));
2251 if (list == NULL) {
2252 PyBuffer_Release(&vsub);
2253 return NULL;
2254 }
2255
2256 #ifdef USE_FAST
2257 i = j = 0;
2258 while (maxsplit-- > 0) {
2259 pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH);
2260 if (pos < 0)
2261 break;
2262 j = i+pos;
2263 SPLIT_ADD(s, i, j);
2264 i = j + n;
2265 }
2266 #else
2267 i = j = 0;
2268 while ((j+n <= len) && (maxsplit-- > 0)) {
2269 for (; j+n <= len; j++) {
2270 if (Py_STRING_MATCH(s, j, sub, n)) {
2271 SPLIT_ADD(s, i, j);
2272 i = j = j + n;
2273 break;
2274 }
2275 }
2276 }
2277 #endif
2278 SPLIT_ADD(s, i, len);
2279 FIX_PREALLOC_SIZE(list);
2044 PyBuffer_Release(&vsub); 2280 PyBuffer_Release(&vsub);
2045 return list; 2281 return list;
2282
2283 onError:
2284 Py_DECREF(list);
2285 PyBuffer_Release(&vsub);
2286 return NULL;
2287 }
2288
2289 /* stringlib's partition shares nullbytes in some cases.
2290 undo this, we don't want the nullbytes to be shared. */
2291 static PyObject *
2292 make_nullbytes_unique(PyObject *result)
2293 {
2294 if (result != NULL) {
2295 int i;
2296 assert(PyTuple_Check(result));
2297 assert(PyTuple_GET_SIZE(result) == 3);
2298 for (i = 0; i < 3; i++) {
2299 if (PyTuple_GET_ITEM(result, i) == (PyObject *)nullbytes) {
2300 PyObject *new = PyByteArray_FromStringAndSize(NULL, 0);
2301 if (new == NULL) {
2302 Py_DECREF(result);
2303 result = NULL;
2304 break;
2305 }
2306 Py_DECREF(nullbytes);
2307 PyTuple_SET_ITEM(result, i, new);
2308 }
2309 }
2310 }
2311 return result;
2046 } 2312 }
2047 2313
2048 PyDoc_STRVAR(partition__doc__, 2314 PyDoc_STRVAR(partition__doc__,
2049 "B.partition(sep) -> (head, sep, tail)\n\ 2315 "B.partition(sep) -> (head, sep, tail)\n\
2050 \n\ 2316 \n\
2051 Search for the separator sep in B, and return the part before it,\n\ 2317 Search for the separator sep in B, and return the part before it,\n\
2052 the separator itself, and the part after it. If the separator is not\n\ 2318 the separator itself, and the part after it. If the separator is not\n\
2053 found, returns B and two empty bytearray objects."); 2319 found, returns B and two empty bytearray objects.");
2054 2320
2055 static PyObject * 2321 static PyObject *
2056 bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) 2322 bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
2057 { 2323 {
2058 PyObject *bytesep, *result; 2324 PyObject *bytesep, *result;
2059 2325
2060 bytesep = PyByteArray_FromObject(sep_obj); 2326 bytesep = PyByteArray_FromObject(sep_obj);
2061 if (! bytesep) 2327 if (! bytesep)
2062 return NULL; 2328 return NULL;
2063 2329
2064 result = stringlib_partition( 2330 result = stringlib_partition(
2065 (PyObject*) self, 2331 (PyObject*) self,
2066 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), 2332 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2067 bytesep, 2333 bytesep,
2068 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep) 2334 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2069 ); 2335 );
2070 2336
2071 Py_DECREF(bytesep); 2337 Py_DECREF(bytesep);
2072 return result; 2338 return make_nullbytes_unique(result);
2073 } 2339 }
2074 2340
2075 PyDoc_STRVAR(rpartition__doc__, 2341 PyDoc_STRVAR(rpartition__doc__,
2076 "B.rpartition(sep) -> (head, sep, tail)\n\ 2342 "B.rpartition(sep) -> (head, sep, tail)\n\
2077 \n\ 2343 \n\
2078 Search for the separator sep in B, starting at the end of B,\n\ 2344 Search for the separator sep in B, starting at the end of B,\n\
2079 and return the part before it, the separator itself, and the\n\ 2345 and return the part before it, the separator itself, and the\n\
2080 part after it. If the separator is not found, returns two empty\n\ 2346 part after it. If the separator is not found, returns two empty\n\
2081 bytearray objects and B."); 2347 bytearray objects and B.");
2082 2348
2083 static PyObject * 2349 static PyObject *
2084 bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj) 2350 bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
2085 { 2351 {
2086 PyObject *bytesep, *result; 2352 PyObject *bytesep, *result;
2087 2353
2088 bytesep = PyByteArray_FromObject(sep_obj); 2354 bytesep = PyByteArray_FromObject(sep_obj);
2089 if (! bytesep) 2355 if (! bytesep)
2090 return NULL; 2356 return NULL;
2091 2357
2092 result = stringlib_rpartition( 2358 result = stringlib_rpartition(
2093 (PyObject*) self, 2359 (PyObject*) self,
2094 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), 2360 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2095 bytesep, 2361 bytesep,
2096 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep) 2362 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2097 ); 2363 );
2098 2364
2099 Py_DECREF(bytesep); 2365 Py_DECREF(bytesep);
2100 return result; 2366 return make_nullbytes_unique(result);
2367 }
2368
2369 Py_LOCAL_INLINE(PyObject *)
2370 rsplit_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
2371 {
2372 register Py_ssize_t i, j, count=0;
2373 PyObject *str;
2374 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2375
2376 if (list == NULL)
2377 return NULL;
2378
2379 i = j = len - 1;
2380 while ((i >= 0) && (maxcount-- > 0)) {
2381 for (; i >= 0; i--) {
2382 if (s[i] == ch) {
2383 SPLIT_ADD(s, i + 1, j + 1);
2384 j = i = i - 1;
2385 break;
2386 }
2387 }
2388 }
2389 if (j >= -1) {
2390 SPLIT_ADD(s, 0, j + 1);
2391 }
2392 FIX_PREALLOC_SIZE(list);
2393 if (PyList_Reverse(list) < 0)
2394 goto onError;
2395
2396 return list;
2397
2398 onError:
2399 Py_DECREF(list);
2400 return NULL;
2401 }
2402
2403 Py_LOCAL_INLINE(PyObject *)
2404 rsplit_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
2405 {
2406 register Py_ssize_t i, j, count = 0;
2407 PyObject *str;
2408 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2409
2410 if (list == NULL)
2411 return NULL;
2412
2413 for (i = j = len - 1; i >= 0; ) {
2414 /* find a token */
2415 while (i >= 0 && Py_ISSPACE(s[i]))
2416 i--;
2417 j = i;
2418 while (i >= 0 && !Py_ISSPACE(s[i]))
2419 i--;
2420 if (j > i) {
2421 if (maxcount-- <= 0)
2422 break;
2423 SPLIT_ADD(s, i + 1, j + 1);
2424 while (i >= 0 && Py_ISSPACE(s[i]))
2425 i--;
2426 j = i;
2427 }
2428 }
2429 if (j >= 0) {
2430 SPLIT_ADD(s, 0, j + 1);
2431 }
2432 FIX_PREALLOC_SIZE(list);
2433 if (PyList_Reverse(list) < 0)
2434 goto onError;
2435
2436 return list;
2437
2438 onError:
2439 Py_DECREF(list);
2440 return NULL;
2101 } 2441 }
2102 2442
2103 PyDoc_STRVAR(rsplit__doc__, 2443 PyDoc_STRVAR(rsplit__doc__,
2104 "B.rsplit(sep[, maxsplit]) -> list of bytearrays\n\ 2444 "B.rsplit(sep[, maxsplit]) -> list of bytearrays\n\
2105 \n\ 2445 \n\
2106 Return a list of the sections in B, using sep as the delimiter,\n\ 2446 Return a list of the sections in B, using sep as the delimiter,\n\
2107 starting at the end of B and working to the front.\n\ 2447 starting at the end of B and working to the front.\n\
2108 If sep is not given, B is split on ASCII whitespace characters\n\ 2448 If sep is not given, B is split on ASCII whitespace characters\n\
2109 (space, tab, return, newline, formfeed, vertical tab).\n\ 2449 (space, tab, return, newline, formfeed, vertical tab).\n\
2110 If maxsplit is given, at most maxsplit splits are done."); 2450 If maxsplit is given, at most maxsplit splits are done.");
2111 2451
2112 static PyObject * 2452 static PyObject *
2113 bytearray_rsplit(PyByteArrayObject *self, PyObject *args) 2453 bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
2114 { 2454 {
2115 Py_ssize_t len = PyByteArray_GET_SIZE(self), n; 2455 Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
2116 Py_ssize_t maxsplit = -1; 2456 Py_ssize_t maxsplit = -1, count = 0;
2117 const char *s = PyByteArray_AS_STRING(self), *sub; 2457 const char *s = PyByteArray_AS_STRING(self), *sub;
2118 PyObject *list, *subobj = Py_None; 2458 PyObject *list, *str, *subobj = Py_None;
2119 Py_buffer vsub; 2459 Py_buffer vsub;
2120 2460
2121 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit)) 2461 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2122 return NULL; 2462 return NULL;
2123 if (maxsplit < 0) 2463 if (maxsplit < 0)
2124 maxsplit = PY_SSIZE_T_MAX; 2464 maxsplit = PY_SSIZE_T_MAX;
2125 2465
2126 if (subobj == Py_None) 2466 if (subobj == Py_None)
2127 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); 2467 return rsplit_whitespace(s, len, maxsplit);
2128 2468
2129 if (_getbuffer(subobj, &vsub) < 0) 2469 if (_getbuffer(subobj, &vsub) < 0)
2130 return NULL; 2470 return NULL;
2131 sub = vsub.buf; 2471 sub = vsub.buf;
2132 n = vsub.len; 2472 n = vsub.len;
2133 2473
2134 list = stringlib_rsplit( 2474 if (n == 0) {
2135 (PyObject*) self, s, len, sub, n, maxsplit 2475 PyErr_SetString(PyExc_ValueError, "empty separator");
2136 ); 2476 PyBuffer_Release(&vsub);
2477 return NULL;
2478 }
2479 else if (n == 1) {
2480 list = rsplit_char(s, len, sub[0], maxsplit);
2481 PyBuffer_Release(&vsub);
2482 return list;
2483 }
2484
2485 list = PyList_New(PREALLOC_SIZE(maxsplit));
2486 if (list == NULL) {
2487 PyBuffer_Release(&vsub);
2488 return NULL;
2489 }
2490
2491 j = len;
2492 i = j - n;
2493
2494 while ( (i >= 0) && (maxsplit-- > 0) ) {
2495 for (; i>=0; i--) {
2496 if (Py_STRING_MATCH(s, i, sub, n)) {
2497 SPLIT_ADD(s, i + n, j);
2498 j = i;
2499 i -= n;
2500 break;
2501 }
2502 }
2503 }
2504 SPLIT_ADD(s, 0, j);
2505 FIX_PREALLOC_SIZE(list);
2506 if (PyList_Reverse(list) < 0)
2507 goto onError;
2137 PyBuffer_Release(&vsub); 2508 PyBuffer_Release(&vsub);
2138 return list; 2509 return list;
2510
2511 onError:
2512 Py_DECREF(list);
2513 PyBuffer_Release(&vsub);
2514 return NULL;
2139 } 2515 }
2140 2516
2141 PyDoc_STRVAR(reverse__doc__, 2517 PyDoc_STRVAR(reverse__doc__,
2142 "B.reverse() -> None\n\ 2518 "B.reverse() -> None\n\
2143 \n\ 2519 \n\
2144 Reverse the order of the values in B in place."); 2520 Reverse the order of the values in B in place.");
2145 static PyObject * 2521 static PyObject *
2146 bytearray_reverse(PyByteArrayObject *self, PyObject *unused) 2522 bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
2147 { 2523 {
2148 char swap, *head, *tail; 2524 char swap, *head, *tail;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2304 static PyObject * 2680 static PyObject *
2305 bytearray_pop(PyByteArrayObject *self, PyObject *args) 2681 bytearray_pop(PyByteArrayObject *self, PyObject *args)
2306 { 2682 {
2307 int value; 2683 int value;
2308 Py_ssize_t where = -1, n = Py_SIZE(self); 2684 Py_ssize_t where = -1, n = Py_SIZE(self);
2309 2685
2310 if (!PyArg_ParseTuple(args, "|n:pop", &where)) 2686 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2311 return NULL; 2687 return NULL;
2312 2688
2313 if (n == 0) { 2689 if (n == 0) {
2314 PyErr_SetString(PyExc_IndexError, 2690 PyErr_SetString(PyExc_OverflowError,
2315 "pop from empty bytearray"); 2691 "cannot pop an empty bytearray");
2316 return NULL; 2692 return NULL;
2317 } 2693 }
2318 if (where < 0) 2694 if (where < 0)
2319 where += Py_SIZE(self); 2695 where += Py_SIZE(self);
2320 if (where < 0 || where >= Py_SIZE(self)) { 2696 if (where < 0 || where >= Py_SIZE(self)) {
2321 PyErr_SetString(PyExc_IndexError, "pop index out of range"); 2697 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2322 return NULL; 2698 return NULL;
2323 } 2699 }
2324 if (!_canresize(self)) 2700 if (!_canresize(self))
2325 return NULL; 2701 return NULL;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 2834
2459 PyDoc_STRVAR(rstrip__doc__, 2835 PyDoc_STRVAR(rstrip__doc__,
2460 "B.rstrip([bytes]) -> bytearray\n\ 2836 "B.rstrip([bytes]) -> bytearray\n\
2461 \n\ 2837 \n\
2462 Strip trailing bytes contained in the argument\n\ 2838 Strip trailing bytes contained in the argument\n\
2463 and return the result as a new bytearray.\n\ 2839 and return the result as a new bytearray.\n\
2464 If the argument is omitted, strip trailing ASCII whitespace."); 2840 If the argument is omitted, strip trailing ASCII whitespace.");
2465 static PyObject * 2841 static PyObject *
2466 bytearray_rstrip(PyByteArrayObject *self, PyObject *args) 2842 bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
2467 { 2843 {
2468 Py_ssize_t right, mysize, argsize; 2844 Py_ssize_t left, right, mysize, argsize;
2469 void *myptr, *argptr; 2845 void *myptr, *argptr;
2470 PyObject *arg = Py_None; 2846 PyObject *arg = Py_None;
2471 Py_buffer varg; 2847 Py_buffer varg;
2472 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg)) 2848 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2473 return NULL; 2849 return NULL;
2474 if (arg == Py_None) { 2850 if (arg == Py_None) {
2475 argptr = "\t\n\r\f\v "; 2851 argptr = "\t\n\r\f\v ";
2476 argsize = 6; 2852 argsize = 6;
2477 } 2853 }
2478 else { 2854 else {
2479 if (_getbuffer(arg, &varg) < 0) 2855 if (_getbuffer(arg, &varg) < 0)
2480 return NULL; 2856 return NULL;
2481 argptr = varg.buf; 2857 argptr = varg.buf;
2482 argsize = varg.len; 2858 argsize = varg.len;
2483 } 2859 }
2484 myptr = self->ob_bytes; 2860 myptr = self->ob_bytes;
2485 mysize = Py_SIZE(self); 2861 mysize = Py_SIZE(self);
2862 left = 0;
2486 right = rstrip_helper(myptr, mysize, argptr, argsize); 2863 right = rstrip_helper(myptr, mysize, argptr, argsize);
2487 if (arg != Py_None) 2864 if (arg != Py_None)
2488 PyBuffer_Release(&varg); 2865 PyBuffer_Release(&varg);
2489 return PyByteArray_FromStringAndSize(self->ob_bytes, right); 2866 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2490 } 2867 }
2491 2868
2492 PyDoc_STRVAR(decode_doc, 2869 PyDoc_STRVAR(decode_doc,
2493 "B.decode(encoding='utf-8', errors='strict') -> str\n\ 2870 "B.decode([encoding[, errors]]) -> str\n\
2494 \n\ 2871 \n\
2495 Decode B using the codec registered for encoding. Default encoding\n\ 2872 Decode B using the codec registered for encoding. encoding defaults\n\
2496 is 'utf-8'. errors may be given to set a different error\n\ 2873 to the default encoding. errors may be given to set a different error\n\
2497 handling scheme. Default is 'strict' meaning that encoding errors raise\n\ 2874 handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2498 a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\ 2875 a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2499 as well as any other name registered with codecs.register_error that is\n\ 2876 as well as any other name registered with codecs.register_error that is\n\
2500 able to handle UnicodeDecodeErrors."); 2877 able to handle UnicodeDecodeErrors.");
2501 2878
2502 static PyObject * 2879 static PyObject *
2503 bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs) 2880 bytearray_decode(PyObject *self, PyObject *args)
2504 { 2881 {
2505 const char *encoding = NULL; 2882 const char *encoding = NULL;
2506 const char *errors = NULL; 2883 const char *errors = NULL;
2507 static char *kwlist[] = {"encoding", "errors", 0}; 2884
2508 2885 if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
2509 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encodi ng, &errors))
2510 return NULL; 2886 return NULL;
2511 if (encoding == NULL) 2887 if (encoding == NULL)
2512 encoding = PyUnicode_GetDefaultEncoding(); 2888 encoding = PyUnicode_GetDefaultEncoding();
2513 return PyUnicode_FromEncodedObject(self, encoding, errors); 2889 return PyUnicode_FromEncodedObject(self, encoding, errors);
2514 } 2890 }
2515 2891
2516 PyDoc_STRVAR(alloc_doc, 2892 PyDoc_STRVAR(alloc_doc,
2517 "B.__alloc__() -> int\n\ 2893 "B.__alloc__() -> int\n\
2518 \n\ 2894 \n\
2519 Return the number of bytes actually allocated."); 2895 Return the number of bytes actually allocated.");
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2593 /* Done */ 2969 /* Done */
2594 Py_DECREF(seq); 2970 Py_DECREF(seq);
2595 return result; 2971 return result;
2596 2972
2597 /* Error handling */ 2973 /* Error handling */
2598 error: 2974 error:
2599 Py_DECREF(seq); 2975 Py_DECREF(seq);
2600 return NULL; 2976 return NULL;
2601 } 2977 }
2602 2978
2603 PyDoc_STRVAR(splitlines__doc__,
2604 "B.splitlines([keepends]) -> list of lines\n\
2605 \n\
2606 Return a list of the lines in B, breaking at line boundaries.\n\
2607 Line breaks are not included in the resulting list unless keepends\n\
2608 is given and true.");
2609
2610 static PyObject*
2611 bytearray_splitlines(PyObject *self, PyObject *args)
2612 {
2613 int keepends = 0;
2614
2615 if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2616 return NULL;
2617
2618 return stringlib_splitlines(
2619 (PyObject*) self, PyByteArray_AS_STRING(self),
2620 PyByteArray_GET_SIZE(self), keepends
2621 );
2622 }
2623
2624 PyDoc_STRVAR(fromhex_doc, 2979 PyDoc_STRVAR(fromhex_doc,
2625 "bytearray.fromhex(string) -> bytearray (static method)\n\ 2980 "bytearray.fromhex(string) -> bytearray (static method)\n\
2626 \n\ 2981 \n\
2627 Create a bytearray object from a string of hexadecimal numbers.\n\ 2982 Create a bytearray object from a string of hexadecimal numbers.\n\
2628 Spaces between two numbers are accepted.\n\ 2983 Spaces between two numbers are accepted.\n\
2629 Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')."); 2984 Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2630 2985
2631 static int 2986 static int
2632 hex_digit_to_int(Py_UNICODE c) 2987 hex_digit_to_int(Py_UNICODE c)
2633 { 2988 {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
2749 3104
2750 static PyMethodDef 3105 static PyMethodDef
2751 bytearray_methods[] = { 3106 bytearray_methods[] = {
2752 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, 3107 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2753 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc}, 3108 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2754 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc}, 3109 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2755 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__}, 3110 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
2756 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, 3111 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2757 _Py_capitalize__doc__}, 3112 _Py_capitalize__doc__},
2758 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, 3113 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
2759 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__},
2760 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__},
2761 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__}, 3114 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
2762 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, deco de_doc}, 3115 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS, decode_doc},
2763 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__} , 3116 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__} ,
2764 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, 3117 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2765 expandtabs__doc__}, 3118 expandtabs__doc__},
2766 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__}, 3119 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2767 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__}, 3120 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2768 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, 3121 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
2769 fromhex_doc}, 3122 fromhex_doc},
2770 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__}, 3123 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2771 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__}, 3124 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
2772 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, 3125 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
(...skipping 21 matching lines...) Expand all
2794 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__}, 3147 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2795 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__}, 3148 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2796 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__}, 3149 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2797 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__}, 3150 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2798 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__}, 3151 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
2799 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, 3152 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
2800 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__} , 3153 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__} ,
2801 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__}, 3154 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2802 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__}, 3155 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2803 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__}, 3156 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
2804 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS, 3157 {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS,
2805 splitlines__doc__}, 3158 splitlines__doc__},
2806 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , 3159 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
2807 startswith__doc__}, 3160 startswith__doc__},
2808 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__}, 3161 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
2809 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, 3162 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2810 _Py_swapcase__doc__}, 3163 _Py_swapcase__doc__},
2811 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, 3164 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
2812 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, 3165 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
2813 translate__doc__}, 3166 translate__doc__},
2814 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, 3167 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2987 } 3340 }
2988 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type); 3341 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
2989 if (it == NULL) 3342 if (it == NULL)
2990 return NULL; 3343 return NULL;
2991 it->it_index = 0; 3344 it->it_index = 0;
2992 Py_INCREF(seq); 3345 Py_INCREF(seq);
2993 it->it_seq = (PyByteArrayObject *)seq; 3346 it->it_seq = (PyByteArrayObject *)seq;
2994 _PyObject_GC_TRACK(it); 3347 _PyObject_GC_TRACK(it);
2995 return (PyObject *)it; 3348 return (PyObject *)it;
2996 } 3349 }
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld cbc36f91f3f7