blob: 4e8107b49112d3befb1aabb84ef2c6b1791f05c7 [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
280_Py_bytes_title(char *result, char *s, Py_ssize_t len)
281{
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
309_Py_bytes_capitalize(char *result, char *s, Py_ssize_t len)
310{
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
339_Py_bytes_swapcase(char *result, char *s, Py_ssize_t len)
340{
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
366static Py_ssize_t
367_getbuffer(PyObject *obj, Py_buffer *view)
368{
369 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
370
371 if (buffer == NULL || buffer->bf_getbuffer == NULL)
372 {
373 PyErr_Format(PyExc_TypeError,
374 "Type %.100s doesn't support the buffer API",
375 Py_TYPE(obj)->tp_name);
376 return -1;
377 }
378
379 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
Antoine Pitrou9b491922010-08-15 17:38:46 +0000380 return -1;
Georg Brandlabc38772009-04-12 15:51:51 +0000381 return view->len;
382}
383
384PyObject *
385_Py_bytes_maketrans(PyObject *args)
386{
Antoine Pitrou9b491922010-08-15 17:38:46 +0000387 PyObject *frm, *to, *res = NULL;
388 Py_buffer bfrm, bto;
389 Py_ssize_t i;
390 char *p;
Georg Brandlabc38772009-04-12 15:51:51 +0000391
Antoine Pitrou9b491922010-08-15 17:38:46 +0000392 bfrm.len = -1;
393 bto.len = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394
Antoine Pitrou9b491922010-08-15 17:38:46 +0000395 if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to))
396 return NULL;
397 if (_getbuffer(frm, &bfrm) < 0)
398 return NULL;
399 if (_getbuffer(to, &bto) < 0)
400 goto done;
401 if (bfrm.len != bto.len) {
402 PyErr_Format(PyExc_ValueError,
403 "maketrans arguments must have same length");
404 goto done;
405 }
406 res = PyBytes_FromStringAndSize(NULL, 256);
407 if (!res) {
408 goto done;
409 }
410 p = PyBytes_AS_STRING(res);
411 for (i = 0; i < 256; i++)
Antoine Pitrou47019e52010-08-15 17:41:31 +0000412 p[i] = (char) i;
Antoine Pitrou9b491922010-08-15 17:38:46 +0000413 for (i = 0; i < bfrm.len; i++) {
414 p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i];
415 }
Georg Brandlabc38772009-04-12 15:51:51 +0000416
Antoine Pitrou9b491922010-08-15 17:38:46 +0000417done:
418 if (bfrm.len != -1)
419 PyBuffer_Release(&bfrm);
420 if (bto.len != -1)
421 PyBuffer_Release(&bto);
422 return res;
Georg Brandlabc38772009-04-12 15:51:51 +0000423}