blob: fe666c631c657e378b0e7075413c7cfc06751667 [file] [log] [blame]
Gregory P. Smith60d241f2007-10-16 06:31:30 +00001#include "Python.h"
2#include "bytes_methods.h"
3
Gregory P. Smith60d241f2007-10-16 06:31:30 +00004PyDoc_STRVAR_shared(_Py_isspace__doc__,
5"B.isspace() -> bool\n\
6\n\
7Return True if all characters in B are whitespace\n\
8and there is at least one character in B, False otherwise.");
9
10PyObject*
11_Py_bytes_isspace(const char *cptr, Py_ssize_t len)
12{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020013 const unsigned char *p
Gregory P. Smith60d241f2007-10-16 06:31:30 +000014 = (unsigned char *) cptr;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020015 const unsigned char *e;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000016
17 /* Shortcut for single character strings */
Eric Smith6dc46f52009-04-27 20:39:49 +000018 if (len == 1 && Py_ISSPACE(*p))
Gregory P. Smith60d241f2007-10-16 06:31:30 +000019 Py_RETURN_TRUE;
20
21 /* Special case for empty strings */
22 if (len == 0)
23 Py_RETURN_FALSE;
24
25 e = p + len;
26 for (; p < e; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000027 if (!Py_ISSPACE(*p))
Gregory P. Smith60d241f2007-10-16 06:31:30 +000028 Py_RETURN_FALSE;
29 }
30 Py_RETURN_TRUE;
31}
32
33
34PyDoc_STRVAR_shared(_Py_isalpha__doc__,
35"B.isalpha() -> bool\n\
36\n\
37Return True if all characters in B are alphabetic\n\
38and there is at least one character in B, False otherwise.");
39
40PyObject*
41_Py_bytes_isalpha(const char *cptr, Py_ssize_t len)
42{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020043 const unsigned char *p
Gregory P. Smith60d241f2007-10-16 06:31:30 +000044 = (unsigned char *) cptr;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020045 const unsigned char *e;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000046
47 /* Shortcut for single character strings */
Eric Smith6dc46f52009-04-27 20:39:49 +000048 if (len == 1 && Py_ISALPHA(*p))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049 Py_RETURN_TRUE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000050
51 /* Special case for empty strings */
52 if (len == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000053 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000054
55 e = p + len;
56 for (; p < e; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000057 if (!Py_ISALPHA(*p))
58 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000059 }
60 Py_RETURN_TRUE;
61}
62
63
64PyDoc_STRVAR_shared(_Py_isalnum__doc__,
65"B.isalnum() -> bool\n\
66\n\
67Return True if all characters in B are alphanumeric\n\
68and there is at least one character in B, False otherwise.");
69
70PyObject*
71_Py_bytes_isalnum(const char *cptr, Py_ssize_t len)
72{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020073 const unsigned char *p
Gregory P. Smith60d241f2007-10-16 06:31:30 +000074 = (unsigned char *) cptr;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020075 const unsigned char *e;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000076
77 /* Shortcut for single character strings */
Eric Smith6dc46f52009-04-27 20:39:49 +000078 if (len == 1 && Py_ISALNUM(*p))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 Py_RETURN_TRUE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000080
81 /* Special case for empty strings */
82 if (len == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000084
85 e = p + len;
86 for (; p < e; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 if (!Py_ISALNUM(*p))
88 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000089 }
90 Py_RETURN_TRUE;
91}
92
93
94PyDoc_STRVAR_shared(_Py_isdigit__doc__,
95"B.isdigit() -> bool\n\
96\n\
97Return True if all characters in B are digits\n\
98and there is at least one character in B, False otherwise.");
99
100PyObject*
101_Py_bytes_isdigit(const char *cptr, Py_ssize_t len)
102{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200103 const unsigned char *p
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000104 = (unsigned char *) cptr;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200105 const unsigned char *e;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000106
107 /* Shortcut for single character strings */
Eric Smith6dc46f52009-04-27 20:39:49 +0000108 if (len == 1 && Py_ISDIGIT(*p))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 Py_RETURN_TRUE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000110
111 /* Special case for empty strings */
112 if (len == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000114
115 e = p + len;
116 for (; p < e; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 if (!Py_ISDIGIT(*p))
118 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000119 }
120 Py_RETURN_TRUE;
121}
122
123
124PyDoc_STRVAR_shared(_Py_islower__doc__,
125"B.islower() -> bool\n\
126\n\
127Return True if all cased characters in B are lowercase and there is\n\
128at least one cased character in B, False otherwise.");
129
130PyObject*
131_Py_bytes_islower(const char *cptr, Py_ssize_t len)
132{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200133 const unsigned char *p
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000134 = (unsigned char *) cptr;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200135 const unsigned char *e;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000136 int cased;
137
138 /* Shortcut for single character strings */
139 if (len == 1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 return PyBool_FromLong(Py_ISLOWER(*p));
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000141
142 /* Special case for empty strings */
143 if (len == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000145
146 e = p + len;
147 cased = 0;
148 for (; p < e; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 if (Py_ISUPPER(*p))
150 Py_RETURN_FALSE;
151 else if (!cased && Py_ISLOWER(*p))
152 cased = 1;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000153 }
154 return PyBool_FromLong(cased);
155}
156
157
158PyDoc_STRVAR_shared(_Py_isupper__doc__,
159"B.isupper() -> bool\n\
160\n\
161Return True if all cased characters in B are uppercase and there is\n\
162at least one cased character in B, False otherwise.");
163
164PyObject*
165_Py_bytes_isupper(const char *cptr, Py_ssize_t len)
166{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200167 const unsigned char *p
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000168 = (unsigned char *) cptr;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200169 const unsigned char *e;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000170 int cased;
171
172 /* Shortcut for single character strings */
173 if (len == 1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 return PyBool_FromLong(Py_ISUPPER(*p));
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000175
176 /* Special case for empty strings */
177 if (len == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000179
180 e = p + len;
181 cased = 0;
182 for (; p < e; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 if (Py_ISLOWER(*p))
184 Py_RETURN_FALSE;
185 else if (!cased && Py_ISUPPER(*p))
186 cased = 1;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000187 }
188 return PyBool_FromLong(cased);
189}
190
191
192PyDoc_STRVAR_shared(_Py_istitle__doc__,
193"B.istitle() -> bool\n\
194\n\
195Return True if B is a titlecased string and there is at least one\n\
196character in B, i.e. uppercase characters may only follow uncased\n\
197characters and lowercase characters only cased ones. Return False\n\
198otherwise.");
199
200PyObject*
201_Py_bytes_istitle(const char *cptr, Py_ssize_t len)
202{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200203 const unsigned char *p
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000204 = (unsigned char *) cptr;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200205 const unsigned char *e;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000206 int cased, previous_is_cased;
207
208 /* Shortcut for single character strings */
209 if (len == 1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 return PyBool_FromLong(Py_ISUPPER(*p));
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000211
212 /* Special case for empty strings */
213 if (len == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000215
216 e = p + len;
217 cased = 0;
218 previous_is_cased = 0;
219 for (; p < e; p++) {
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200220 const unsigned char ch = *p;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 if (Py_ISUPPER(ch)) {
223 if (previous_is_cased)
224 Py_RETURN_FALSE;
225 previous_is_cased = 1;
226 cased = 1;
227 }
228 else if (Py_ISLOWER(ch)) {
229 if (!previous_is_cased)
230 Py_RETURN_FALSE;
231 previous_is_cased = 1;
232 cased = 1;
233 }
234 else
235 previous_is_cased = 0;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000236 }
237 return PyBool_FromLong(cased);
238}
239
240
241PyDoc_STRVAR_shared(_Py_lower__doc__,
242"B.lower() -> copy of B\n\
243\n\
244Return a copy of B with all ASCII characters converted to lowercase.");
245
246void
247_Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len)
248{
Antoine Pitrou9b491922010-08-15 17:38:46 +0000249 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000250
Antoine Pitrou9b491922010-08-15 17:38:46 +0000251 for (i = 0; i < len; i++) {
Antoine Pitrou94f6fa62012-01-08 16:22:46 +0100252 result[i] = Py_TOLOWER((unsigned char) cptr[i]);
Antoine Pitrou9b491922010-08-15 17:38:46 +0000253 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000254}
255
256
257PyDoc_STRVAR_shared(_Py_upper__doc__,
258"B.upper() -> copy of B\n\
259\n\
260Return a copy of B with all ASCII characters converted to uppercase.");
261
262void
263_Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len)
264{
Antoine Pitrou9b491922010-08-15 17:38:46 +0000265 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000266
Antoine Pitrou9b491922010-08-15 17:38:46 +0000267 for (i = 0; i < len; i++) {
Antoine Pitrou94f6fa62012-01-08 16:22:46 +0100268 result[i] = Py_TOUPPER((unsigned char) cptr[i]);
Antoine Pitrou9b491922010-08-15 17:38:46 +0000269 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000270}
271
272
273PyDoc_STRVAR_shared(_Py_title__doc__,
274"B.title() -> copy of B\n\
275\n\
276Return a titlecased version of B, i.e. ASCII words start with uppercase\n\
277characters, all remaining cased characters have lowercase.");
278
279void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200280_Py_bytes_title(char *result, const char *s, Py_ssize_t len)
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000281{
Antoine Pitrou9b491922010-08-15 17:38:46 +0000282 Py_ssize_t i;
283 int previous_is_cased = 0;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000284
Antoine Pitrou9b491922010-08-15 17:38:46 +0000285 for (i = 0; i < len; i++) {
286 int c = Py_CHARMASK(*s++);
287 if (Py_ISLOWER(c)) {
288 if (!previous_is_cased)
289 c = Py_TOUPPER(c);
290 previous_is_cased = 1;
291 } else if (Py_ISUPPER(c)) {
292 if (previous_is_cased)
293 c = Py_TOLOWER(c);
294 previous_is_cased = 1;
295 } else
296 previous_is_cased = 0;
297 *result++ = c;
298 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000299}
300
301
302PyDoc_STRVAR_shared(_Py_capitalize__doc__,
303"B.capitalize() -> copy of B\n\
304\n\
Senthil Kumarane51ee8a2010-07-05 12:00:56 +0000305Return a copy of B with only its first character capitalized (ASCII)\n\
306and the rest lower-cased.");
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000307
308void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200309_Py_bytes_capitalize(char *result, const char *s, Py_ssize_t len)
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000310{
Antoine Pitrou9b491922010-08-15 17:38:46 +0000311 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000312
Antoine Pitrou9b491922010-08-15 17:38:46 +0000313 if (0 < len) {
314 int c = Py_CHARMASK(*s++);
315 if (Py_ISLOWER(c))
316 *result = Py_TOUPPER(c);
317 else
318 *result = c;
319 result++;
320 }
321 for (i = 1; i < len; i++) {
322 int c = Py_CHARMASK(*s++);
323 if (Py_ISUPPER(c))
324 *result = Py_TOLOWER(c);
325 else
326 *result = c;
327 result++;
328 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000329}
330
331
332PyDoc_STRVAR_shared(_Py_swapcase__doc__,
333"B.swapcase() -> copy of B\n\
334\n\
335Return a copy of B with uppercase ASCII characters converted\n\
336to lowercase ASCII and vice versa.");
337
338void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200339_Py_bytes_swapcase(char *result, const char *s, Py_ssize_t len)
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000340{
Antoine Pitrou9b491922010-08-15 17:38:46 +0000341 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000342
Antoine Pitrou9b491922010-08-15 17:38:46 +0000343 for (i = 0; i < len; i++) {
344 int c = Py_CHARMASK(*s++);
345 if (Py_ISLOWER(c)) {
346 *result = Py_TOUPPER(c);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 }
Antoine Pitrou9b491922010-08-15 17:38:46 +0000348 else if (Py_ISUPPER(c)) {
349 *result = Py_TOLOWER(c);
350 }
351 else
352 *result = c;
353 result++;
354 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000355}
356
Georg Brandlabc38772009-04-12 15:51:51 +0000357
358PyDoc_STRVAR_shared(_Py_maketrans__doc__,
359"B.maketrans(frm, to) -> translation table\n\
360\n\
Senthil Kumaran84e3ccc2011-06-27 09:06:45 -0700361Return a translation table (a bytes object of length 256) suitable\n\
362for use in the bytes or bytearray translate method where each byte\n\
363in frm is mapped to the byte at the same position in to.\n\
364The bytes objects frm and to must be of the same length.");
Georg Brandlabc38772009-04-12 15:51:51 +0000365
Georg Brandlabc38772009-04-12 15:51:51 +0000366PyObject *
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +0200367_Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to)
Georg Brandlabc38772009-04-12 15:51:51 +0000368{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +0200369 PyObject *res = NULL;
Antoine Pitrou9b491922010-08-15 17:38:46 +0000370 Py_ssize_t i;
371 char *p;
Georg Brandlabc38772009-04-12 15:51:51 +0000372
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +0200373 if (frm->len != to->len) {
Antoine Pitrou9b491922010-08-15 17:38:46 +0000374 PyErr_Format(PyExc_ValueError,
375 "maketrans arguments must have same length");
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +0200376 return NULL;
Antoine Pitrou9b491922010-08-15 17:38:46 +0000377 }
378 res = PyBytes_FromStringAndSize(NULL, 256);
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +0200379 if (!res)
380 return NULL;
Antoine Pitrou9b491922010-08-15 17:38:46 +0000381 p = PyBytes_AS_STRING(res);
382 for (i = 0; i < 256; i++)
Antoine Pitrou47019e52010-08-15 17:41:31 +0000383 p[i] = (char) i;
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +0200384 for (i = 0; i < frm->len; i++) {
385 p[((unsigned char *)frm->buf)[i]] = ((char *)to->buf)[i];
Antoine Pitrou9b491922010-08-15 17:38:46 +0000386 }
Georg Brandlabc38772009-04-12 15:51:51 +0000387
Antoine Pitrou9b491922010-08-15 17:38:46 +0000388 return res;
Georg Brandlabc38772009-04-12 15:51:51 +0000389}
Serhiy Storchakadd40fc32016-05-04 22:23:26 +0300390
391#define FASTSEARCH fastsearch
392#define STRINGLIB(F) stringlib_##F
393#define STRINGLIB_CHAR char
394#define STRINGLIB_SIZEOF_CHAR 1
395
396#include "stringlib/fastsearch.h"
397#include "stringlib/count.h"
398#include "stringlib/find.h"
399
400/*
401Wraps stringlib_parse_args_finds() and additionally checks whether the
402first argument is an integer in range(0, 256).
403
404If this is the case, writes the integer value to the byte parameter
405and sets subobj to NULL. Otherwise, sets the first argument to subobj
406and doesn't touch byte. The other parameters are similar to those of
407stringlib_parse_args_finds().
408*/
409
410Py_LOCAL_INLINE(int)
411parse_args_finds_byte(const char *function_name, PyObject *args,
412 PyObject **subobj, char *byte,
413 Py_ssize_t *start, Py_ssize_t *end)
414{
415 PyObject *tmp_subobj;
416 Py_ssize_t ival;
417 PyObject *err;
418
419 if(!stringlib_parse_args_finds(function_name, args, &tmp_subobj,
420 start, end))
421 return 0;
422
423 if (!PyNumber_Check(tmp_subobj)) {
424 *subobj = tmp_subobj;
425 return 1;
426 }
427
428 ival = PyNumber_AsSsize_t(tmp_subobj, PyExc_OverflowError);
429 if (ival == -1) {
430 err = PyErr_Occurred();
431 if (err && !PyErr_GivenExceptionMatches(err, PyExc_OverflowError)) {
432 PyErr_Clear();
433 *subobj = tmp_subobj;
434 return 1;
435 }
436 }
437
438 if (ival < 0 || ival > 255) {
439 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
440 return 0;
441 }
442
443 *subobj = NULL;
444 *byte = (char)ival;
445 return 1;
446}
447
448/* helper macro to fixup start/end slice values */
449#define ADJUST_INDICES(start, end, len) \
450 if (end > len) \
451 end = len; \
452 else if (end < 0) { \
453 end += len; \
454 if (end < 0) \
455 end = 0; \
456 } \
457 if (start < 0) { \
458 start += len; \
459 if (start < 0) \
460 start = 0; \
461 }
462
463Py_LOCAL_INLINE(Py_ssize_t)
464find_internal(const char *str, Py_ssize_t len,
465 const char *function_name, PyObject *args, int dir)
466{
467 PyObject *subobj;
468 char byte;
469 Py_buffer subbuf;
470 const char *sub;
471 Py_ssize_t sub_len;
472 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
473 Py_ssize_t res;
474
475 if (!parse_args_finds_byte(function_name, args,
476 &subobj, &byte, &start, &end))
477 return -2;
478
479 if (subobj) {
480 if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
481 return -2;
482
483 sub = subbuf.buf;
484 sub_len = subbuf.len;
485 }
486 else {
487 sub = &byte;
488 sub_len = 1;
489 }
490
491 ADJUST_INDICES(start, end, len);
492 if (end - start < sub_len)
493 res = -1;
494 else if (sub_len == 1) {
495 if (dir > 0)
496 res = stringlib_find_char(
497 str + start, end - start,
498 *sub);
499 else
500 res = stringlib_rfind_char(
501 str + start, end - start,
502 *sub);
503 if (res >= 0)
504 res += start;
505 }
506 else {
507 if (dir > 0)
508 res = stringlib_find_slice(
509 str, len,
510 sub, sub_len, start, end);
511 else
512 res = stringlib_rfind_slice(
513 str, len,
514 sub, sub_len, start, end);
515 }
516
517 if (subobj)
518 PyBuffer_Release(&subbuf);
519
520 return res;
521}
522
523PyDoc_STRVAR_shared(_Py_find__doc__,
524"B.find(sub[, start[, end]]) -> int\n\
525\n\
526Return the lowest index in B where subsection sub is found,\n\
527such that sub is contained within B[start,end]. Optional\n\
528arguments start and end are interpreted as in slice notation.\n\
529\n\
530Return -1 on failure.");
531
532PyObject *
533_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *args)
534{
535 Py_ssize_t result = find_internal(str, len, "find", args, +1);
536 if (result == -2)
537 return NULL;
538 return PyLong_FromSsize_t(result);
539}
540
541PyDoc_STRVAR_shared(_Py_index__doc__,
542"B.index(sub[, start[, end]]) -> int\n\
543\n\
544Like B.find() but raise ValueError when the subsection is not found.");
545
546PyObject *
547_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args)
548{
549 Py_ssize_t result = find_internal(str, len, "index", args, +1);
550 if (result == -2)
551 return NULL;
552 if (result == -1) {
553 PyErr_SetString(PyExc_ValueError,
554 "subsection not found");
555 return NULL;
556 }
557 return PyLong_FromSsize_t(result);
558}
559
560PyDoc_STRVAR_shared(_Py_rfind__doc__,
561"B.rfind(sub[, start[, end]]) -> int\n\
562\n\
563Return the highest index in B where subsection sub is found,\n\
564such that sub is contained within B[start,end]. Optional\n\
565arguments start and end are interpreted as in slice notation.\n\
566\n\
567Return -1 on failure.");
568
569PyObject *
570_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *args)
571{
572 Py_ssize_t result = find_internal(str, len, "rfind", args, -1);
573 if (result == -2)
574 return NULL;
575 return PyLong_FromSsize_t(result);
576}
577
578PyDoc_STRVAR_shared(_Py_rindex__doc__,
579"B.rindex(sub[, start[, end]]) -> int\n\
580\n\
581Like B.rfind() but raise ValueError when the subsection is not found.");
582
583PyObject *
584_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args)
585{
586 Py_ssize_t result = find_internal(str, len, "rindex", args, -1);
587 if (result == -2)
588 return NULL;
589 if (result == -1) {
590 PyErr_SetString(PyExc_ValueError,
591 "subsection not found");
592 return NULL;
593 }
594 return PyLong_FromSsize_t(result);
595}
596
597PyDoc_STRVAR_shared(_Py_count__doc__,
598"B.count(sub[, start[, end]]) -> int\n\
599\n\
600Return the number of non-overlapping occurrences of subsection sub in\n\
601bytes B[start:end]. Optional arguments start and end are interpreted\n\
602as in slice notation.");
603
604PyObject *
605_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *args)
606{
607 PyObject *sub_obj;
608 const char *sub;
609 Py_ssize_t sub_len;
610 char byte;
611 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
612
613 Py_buffer vsub;
614 PyObject *count_obj;
615
616 if (!parse_args_finds_byte("count", args,
617 &sub_obj, &byte, &start, &end))
618 return NULL;
619
620 if (sub_obj) {
621 if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
622 return NULL;
623
624 sub = vsub.buf;
625 sub_len = vsub.len;
626 }
627 else {
628 sub = &byte;
629 sub_len = 1;
630 }
631
632 ADJUST_INDICES(start, end, len);
633
634 count_obj = PyLong_FromSsize_t(
635 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
636 );
637
638 if (sub_obj)
639 PyBuffer_Release(&vsub);
640
641 return count_obj;
642}
643
644int
645_Py_bytes_contains(const char *str, Py_ssize_t len, PyObject *arg)
646{
647 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
648 if (ival == -1 && PyErr_Occurred()) {
649 Py_buffer varg;
650 Py_ssize_t pos;
651 PyErr_Clear();
652 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
653 return -1;
654 pos = stringlib_find(str, len,
655 varg.buf, varg.len, 0);
656 PyBuffer_Release(&varg);
657 return pos >= 0;
658 }
659 if (ival < 0 || ival >= 256) {
660 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
661 return -1;
662 }
663
664 return memchr(str, (int) ival, len) != NULL;
665}
666
667
668/* Matches the end (direction >= 0) or start (direction < 0) of the buffer
669 * against substr, using the start and end arguments. Returns
670 * -1 on error, 0 if not found and 1 if found.
671 */
672Py_LOCAL(int)
673tailmatch(const char *str, Py_ssize_t len, PyObject *substr,
674 Py_ssize_t start, Py_ssize_t end, int direction)
675{
676 Py_buffer sub_view = {NULL, NULL};
677 const char *sub;
678 Py_ssize_t slen;
679
680 if (PyBytes_Check(substr)) {
681 sub = PyBytes_AS_STRING(substr);
682 slen = PyBytes_GET_SIZE(substr);
683 }
684 else {
685 if (PyObject_GetBuffer(substr, &sub_view, PyBUF_SIMPLE) != 0)
686 return -1;
687 sub = sub_view.buf;
688 slen = sub_view.len;
689 }
690
691 ADJUST_INDICES(start, end, len);
692
693 if (direction < 0) {
694 /* startswith */
695 if (start + slen > len)
696 goto notfound;
697 } else {
698 /* endswith */
699 if (end - start < slen || start > len)
700 goto notfound;
701
702 if (end - slen > start)
703 start = end - slen;
704 }
705 if (end - start < slen)
706 goto notfound;
707 if (memcmp(str + start, sub, slen) != 0)
708 goto notfound;
709
710 PyBuffer_Release(&sub_view);
711 return 1;
712
713notfound:
714 PyBuffer_Release(&sub_view);
715 return 0;
716}
717
718Py_LOCAL(PyObject *)
719_Py_bytes_tailmatch(const char *str, Py_ssize_t len,
720 const char *function_name, PyObject *args,
721 int direction)
722{
723 Py_ssize_t start = 0;
724 Py_ssize_t end = PY_SSIZE_T_MAX;
725 PyObject *subobj;
726 int result;
727
728 if (!stringlib_parse_args_finds(function_name, args, &subobj, &start, &end))
729 return NULL;
730 if (PyTuple_Check(subobj)) {
731 Py_ssize_t i;
732 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
733 result = tailmatch(str, len, PyTuple_GET_ITEM(subobj, i),
734 start, end, direction);
735 if (result == -1)
736 return NULL;
737 else if (result) {
738 Py_RETURN_TRUE;
739 }
740 }
741 Py_RETURN_FALSE;
742 }
743 result = tailmatch(str, len, subobj, start, end, direction);
744 if (result == -1) {
745 if (PyErr_ExceptionMatches(PyExc_TypeError))
746 PyErr_Format(PyExc_TypeError,
747 "%s first arg must be bytes or a tuple of bytes, "
748 "not %s",
749 function_name, Py_TYPE(subobj)->tp_name);
750 return NULL;
751 }
752 else
753 return PyBool_FromLong(result);
754}
755
756PyDoc_STRVAR_shared(_Py_startswith__doc__,
757"B.startswith(prefix[, start[, end]]) -> bool\n\
758\n\
759Return True if B starts with the specified prefix, False otherwise.\n\
760With optional start, test B beginning at that position.\n\
761With optional end, stop comparing B at that position.\n\
762prefix can also be a tuple of bytes to try.");
763
764PyObject *
765_Py_bytes_startswith(const char *str, Py_ssize_t len, PyObject *args)
766{
767 return _Py_bytes_tailmatch(str, len, "startswith", args, -1);
768}
769
770PyDoc_STRVAR_shared(_Py_endswith__doc__,
771"B.endswith(suffix[, start[, end]]) -> bool\n\
772\n\
773Return True if B ends with the specified suffix, False otherwise.\n\
774With optional start, test B beginning at that position.\n\
775With optional end, stop comparing B at that position.\n\
776suffix can also be a tuple of bytes to try.");
777
778PyObject *
779_Py_bytes_endswith(const char *str, Py_ssize_t len, PyObject *args)
780{
781 return _Py_bytes_tailmatch(str, len, "endswith", args, +1);
782}
783
784PyDoc_STRVAR_shared(_Py_expandtabs__doc__,
785"B.expandtabs(tabsize=8) -> copy of B\n\
786\n\
787Return a copy of B where all tab characters are expanded using spaces.\n\
788If tabsize is not given, a tab size of 8 characters is assumed.");
789
790PyDoc_STRVAR_shared(_Py_ljust__doc__,
791"B.ljust(width[, fillchar]) -> copy of B\n"
792"\n"
793"Return B left justified in a string of length width. Padding is\n"
794"done using the specified fill character (default is a space).");
795
796PyDoc_STRVAR_shared(_Py_rjust__doc__,
797"B.rjust(width[, fillchar]) -> copy of B\n"
798"\n"
799"Return B right justified in a string of length width. Padding is\n"
800"done using the specified fill character (default is a space)");
801
802PyDoc_STRVAR_shared(_Py_center__doc__,
803"B.center(width[, fillchar]) -> copy of B\n"
804"\n"
805"Return B centered in a string of length width. Padding is\n"
806"done using the specified fill character (default is a space).");
807
808PyDoc_STRVAR_shared(_Py_zfill__doc__,
809"B.zfill(width) -> copy of B\n"
810"\n"
811"Pad a numeric string B with zeros on the left, to fill a field\n"
812"of the specified width. B is never truncated.");
813