blob: 215a1fac0ffee33023b12efed4ae8d7337ed467b [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{
13 register const unsigned char *p
14 = (unsigned char *) cptr;
15 register const unsigned char *e;
16
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 Pitrou7f14f0d2010-05-09 16:14:21 +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{
43 register const unsigned char *p
44 = (unsigned char *) cptr;
45 register const unsigned char *e;
46
47 /* Shortcut for single character strings */
Eric Smith6dc46f52009-04-27 20:39:49 +000048 if (len == 1 && Py_ISALPHA(*p))
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000049 Py_RETURN_TRUE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000050
51 /* Special case for empty strings */
52 if (len == 0)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000053 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000054
55 e = p + len;
56 for (; p < e; p++) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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{
73 register const unsigned char *p
74 = (unsigned char *) cptr;
75 register const unsigned char *e;
76
77 /* Shortcut for single character strings */
Eric Smith6dc46f52009-04-27 20:39:49 +000078 if (len == 1 && Py_ISALNUM(*p))
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000079 Py_RETURN_TRUE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000080
81 /* Special case for empty strings */
82 if (len == 0)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000083 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000084
85 e = p + len;
86 for (; p < e; p++) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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{
103 register const unsigned char *p
104 = (unsigned char *) cptr;
105 register const unsigned char *e;
106
107 /* Shortcut for single character strings */
Eric Smith6dc46f52009-04-27 20:39:49 +0000108 if (len == 1 && Py_ISDIGIT(*p))
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000109 Py_RETURN_TRUE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000110
111 /* Special case for empty strings */
112 if (len == 0)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000113 Py_RETURN_FALSE;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000114
115 e = p + len;
116 for (; p < e; p++) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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{
133 register const unsigned char *p
134 = (unsigned char *) cptr;
135 register const unsigned char *e;
136 int cased;
137
138 /* Shortcut for single character strings */
139 if (len == 1)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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{
167 register const unsigned char *p
168 = (unsigned char *) cptr;
169 register const unsigned char *e;
170 int cased;
171
172 /* Shortcut for single character strings */
173 if (len == 1)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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{
203 register const unsigned char *p
204 = (unsigned char *) cptr;
205 register const unsigned char *e;
206 int cased, previous_is_cased;
207
208 /* Shortcut for single character strings */
209 if (len == 1)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +0000220 register const unsigned char ch = *p;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000221
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +0000249 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000250
251 /*
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000252 newobj = PyBytes_FromStringAndSize(NULL, len);
253 if (!newobj)
254 return NULL;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000255
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000256 s = PyBytes_AS_STRING(newobj);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000257 */
258
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000259 Py_MEMCPY(result, cptr, len);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000260
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000261 for (i = 0; i < len; i++) {
262 int c = Py_CHARMASK(result[i]);
263 if (Py_ISUPPER(c))
264 result[i] = Py_TOLOWER(c);
265 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000266}
267
268
269PyDoc_STRVAR_shared(_Py_upper__doc__,
270"B.upper() -> copy of B\n\
271\n\
272Return a copy of B with all ASCII characters converted to uppercase.");
273
274void
275_Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len)
276{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000277 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000278
279 /*
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000280 newobj = PyBytes_FromStringAndSize(NULL, len);
281 if (!newobj)
282 return NULL;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000283
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000284 s = PyBytes_AS_STRING(newobj);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000285 */
286
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000287 Py_MEMCPY(result, cptr, len);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000288
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000289 for (i = 0; i < len; i++) {
290 int c = Py_CHARMASK(result[i]);
291 if (Py_ISLOWER(c))
292 result[i] = Py_TOUPPER(c);
293 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000294}
295
296
297PyDoc_STRVAR_shared(_Py_title__doc__,
298"B.title() -> copy of B\n\
299\n\
300Return a titlecased version of B, i.e. ASCII words start with uppercase\n\
301characters, all remaining cased characters have lowercase.");
302
303void
304_Py_bytes_title(char *result, char *s, Py_ssize_t len)
305{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000306 Py_ssize_t i;
307 int previous_is_cased = 0;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000308
309 /*
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000310 newobj = PyBytes_FromStringAndSize(NULL, len);
311 if (newobj == NULL)
312 return NULL;
313 s_new = PyBytes_AsString(newobj);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000314 */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000315 for (i = 0; i < len; i++) {
316 int c = Py_CHARMASK(*s++);
317 if (Py_ISLOWER(c)) {
318 if (!previous_is_cased)
319 c = Py_TOUPPER(c);
320 previous_is_cased = 1;
321 } else if (Py_ISUPPER(c)) {
322 if (previous_is_cased)
323 c = Py_TOLOWER(c);
324 previous_is_cased = 1;
325 } else
326 previous_is_cased = 0;
327 *result++ = c;
328 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000329}
330
331
332PyDoc_STRVAR_shared(_Py_capitalize__doc__,
333"B.capitalize() -> copy of B\n\
334\n\
335Return a copy of B with only its first character capitalized (ASCII).");
336
337void
338_Py_bytes_capitalize(char *result, char *s, Py_ssize_t len)
339{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000340 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000341
342 /*
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000343 newobj = PyBytes_FromStringAndSize(NULL, len);
344 if (newobj == NULL)
345 return NULL;
346 s_new = PyBytes_AsString(newobj);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000347 */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000348 if (0 < len) {
349 int c = Py_CHARMASK(*s++);
350 if (Py_ISLOWER(c))
351 *result = Py_TOUPPER(c);
352 else
353 *result = c;
354 result++;
355 }
356 for (i = 1; i < len; i++) {
357 int c = Py_CHARMASK(*s++);
358 if (Py_ISUPPER(c))
359 *result = Py_TOLOWER(c);
360 else
361 *result = c;
362 result++;
363 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000364}
365
366
367PyDoc_STRVAR_shared(_Py_swapcase__doc__,
368"B.swapcase() -> copy of B\n\
369\n\
370Return a copy of B with uppercase ASCII characters converted\n\
371to lowercase ASCII and vice versa.");
372
373void
374_Py_bytes_swapcase(char *result, char *s, Py_ssize_t len)
375{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000376 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000377
378 /*
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000379 newobj = PyBytes_FromStringAndSize(NULL, len);
380 if (newobj == NULL)
381 return NULL;
382 s_new = PyBytes_AsString(newobj);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000383 */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000384 for (i = 0; i < len; i++) {
385 int c = Py_CHARMASK(*s++);
386 if (Py_ISLOWER(c)) {
387 *result = Py_TOUPPER(c);
388 }
389 else if (Py_ISUPPER(c)) {
390 *result = Py_TOLOWER(c);
391 }
392 else
393 *result = c;
394 result++;
395 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000396}
397
Georg Brandlabc38772009-04-12 15:51:51 +0000398
399PyDoc_STRVAR_shared(_Py_maketrans__doc__,
400"B.maketrans(frm, to) -> translation table\n\
401\n\
402Return a translation table (a bytes object of length 256)\n\
403suitable for use in bytes.translate where each byte in frm is\n\
404mapped to the byte at the same position in to.\n\
405The strings frm and to must be of the same length.");
406
407static Py_ssize_t
408_getbuffer(PyObject *obj, Py_buffer *view)
409{
410 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
411
412 if (buffer == NULL || buffer->bf_getbuffer == NULL)
413 {
414 PyErr_Format(PyExc_TypeError,
415 "Type %.100s doesn't support the buffer API",
416 Py_TYPE(obj)->tp_name);
417 return -1;
418 }
419
420 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
421 return -1;
422 return view->len;
423}
424
425PyObject *
426_Py_bytes_maketrans(PyObject *args)
427{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000428 PyObject *frm, *to, *res = NULL;
429 Py_buffer bfrm, bto;
430 Py_ssize_t i;
431 char *p;
Georg Brandlabc38772009-04-12 15:51:51 +0000432
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000433 bfrm.len = -1;
434 bto.len = -1;
435
436 if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to))
437 return NULL;
438 if (_getbuffer(frm, &bfrm) < 0)
439 return NULL;
440 if (_getbuffer(to, &bto) < 0)
441 goto done;
442 if (bfrm.len != bto.len) {
443 PyErr_Format(PyExc_ValueError,
444 "maketrans arguments must have same length");
445 goto done;
446 }
447 res = PyBytes_FromStringAndSize(NULL, 256);
448 if (!res) {
449 goto done;
450 }
451 p = PyBytes_AS_STRING(res);
452 for (i = 0; i < 256; i++)
453 p[i] = i;
454 for (i = 0; i < bfrm.len; i++) {
455 p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i];
456 }
Georg Brandlabc38772009-04-12 15:51:51 +0000457
458 done:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000459 if (bfrm.len != -1)
460 PyBuffer_Release(&bfrm);
461 if (bto.len != -1)
462 PyBuffer_Release(&bto);
463 return res;
Georg Brandlabc38772009-04-12 15:51:51 +0000464}