blob: b41b3d9b80be7bcee762c77fc96203785bd8350e [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 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{
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 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{
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 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{
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 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{
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 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{
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 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{
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 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 Pitrouf95a1b32010-05-09 15:52:27 +0000220 register 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 Pitrouf95a1b32010-05-09 15:52:27 +0000249 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000250
251 /*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 newobj = PyBytes_FromStringAndSize(NULL, len);
253 if (!newobj)
254 return NULL;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 s = PyBytes_AS_STRING(newobj);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000257 */
258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 Py_MEMCPY(result, cptr, len);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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 Pitrouf95a1b32010-05-09 15:52:27 +0000277 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000278
279 /*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 newobj = PyBytes_FromStringAndSize(NULL, len);
281 if (!newobj)
282 return NULL;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 s = PyBytes_AS_STRING(newobj);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000285 */
286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 Py_MEMCPY(result, cptr, len);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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 Pitrouf95a1b32010-05-09 15:52:27 +0000306 Py_ssize_t i;
307 int previous_is_cased = 0;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000308
309 /*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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 Pitrouf95a1b32010-05-09 15:52:27 +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\
Senthil Kumarane51ee8a2010-07-05 12:00:56 +0000335Return a copy of B with only its first character capitalized (ASCII)\n\
336and the rest lower-cased.");
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000337
338void
339_Py_bytes_capitalize(char *result, char *s, Py_ssize_t len)
340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000342
343 /*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 newobj = PyBytes_FromStringAndSize(NULL, len);
345 if (newobj == NULL)
346 return NULL;
347 s_new = PyBytes_AsString(newobj);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000348 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 if (0 < len) {
350 int c = Py_CHARMASK(*s++);
351 if (Py_ISLOWER(c))
352 *result = Py_TOUPPER(c);
353 else
354 *result = c;
355 result++;
356 }
357 for (i = 1; i < len; i++) {
358 int c = Py_CHARMASK(*s++);
359 if (Py_ISUPPER(c))
360 *result = Py_TOLOWER(c);
361 else
362 *result = c;
363 result++;
364 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000365}
366
367
368PyDoc_STRVAR_shared(_Py_swapcase__doc__,
369"B.swapcase() -> copy of B\n\
370\n\
371Return a copy of B with uppercase ASCII characters converted\n\
372to lowercase ASCII and vice versa.");
373
374void
375_Py_bytes_swapcase(char *result, char *s, Py_ssize_t len)
376{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 Py_ssize_t i;
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000378
379 /*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 newobj = PyBytes_FromStringAndSize(NULL, len);
381 if (newobj == NULL)
382 return NULL;
383 s_new = PyBytes_AsString(newobj);
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000384 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 for (i = 0; i < len; i++) {
386 int c = Py_CHARMASK(*s++);
387 if (Py_ISLOWER(c)) {
388 *result = Py_TOUPPER(c);
389 }
390 else if (Py_ISUPPER(c)) {
391 *result = Py_TOLOWER(c);
392 }
393 else
394 *result = c;
395 result++;
396 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000397}
398
Georg Brandlabc38772009-04-12 15:51:51 +0000399
400PyDoc_STRVAR_shared(_Py_maketrans__doc__,
401"B.maketrans(frm, to) -> translation table\n\
402\n\
403Return a translation table (a bytes object of length 256)\n\
404suitable for use in bytes.translate where each byte in frm is\n\
405mapped to the byte at the same position in to.\n\
406The strings frm and to must be of the same length.");
407
408static Py_ssize_t
409_getbuffer(PyObject *obj, Py_buffer *view)
410{
411 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
412
413 if (buffer == NULL || buffer->bf_getbuffer == NULL)
414 {
415 PyErr_Format(PyExc_TypeError,
416 "Type %.100s doesn't support the buffer API",
417 Py_TYPE(obj)->tp_name);
418 return -1;
419 }
420
421 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
422 return -1;
423 return view->len;
424}
425
426PyObject *
427_Py_bytes_maketrans(PyObject *args)
428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 PyObject *frm, *to, *res = NULL;
430 Py_buffer bfrm, bto;
431 Py_ssize_t i;
432 char *p;
Georg Brandlabc38772009-04-12 15:51:51 +0000433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 bfrm.len = -1;
435 bto.len = -1;
436
437 if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to))
438 return NULL;
439 if (_getbuffer(frm, &bfrm) < 0)
440 return NULL;
441 if (_getbuffer(to, &bto) < 0)
442 goto done;
443 if (bfrm.len != bto.len) {
444 PyErr_Format(PyExc_ValueError,
445 "maketrans arguments must have same length");
446 goto done;
447 }
448 res = PyBytes_FromStringAndSize(NULL, 256);
449 if (!res) {
450 goto done;
451 }
452 p = PyBytes_AS_STRING(res);
453 for (i = 0; i < 256; i++)
454 p[i] = i;
455 for (i = 0; i < bfrm.len; i++) {
456 p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i];
457 }
Georg Brandlabc38772009-04-12 15:51:51 +0000458
459 done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 if (bfrm.len != -1)
461 PyBuffer_Release(&bfrm);
462 if (bto.len != -1)
463 PyBuffer_Release(&bto);
464 return res;
Georg Brandlabc38772009-04-12 15:51:51 +0000465}