Line data Source code
1 : #include "Python.h"
2 : #include "bytes_methods.h"
3 :
4 : PyDoc_STRVAR_shared(_Py_isspace__doc__,
5 : "B.isspace() -> bool\n\
6 : \n\
7 : Return True if all characters in B are whitespace\n\
8 : and there is at least one character in B, False otherwise.");
9 :
10 : PyObject*
11 0 : _Py_bytes_isspace(const char *cptr, Py_ssize_t len)
12 : {
13 0 : register const unsigned char *p
14 : = (unsigned char *) cptr;
15 : register const unsigned char *e;
16 :
17 : /* Shortcut for single character strings */
18 0 : if (len == 1 && Py_ISSPACE(*p))
19 0 : Py_RETURN_TRUE;
20 :
21 : /* Special case for empty strings */
22 0 : if (len == 0)
23 0 : Py_RETURN_FALSE;
24 :
25 0 : e = p + len;
26 0 : for (; p < e; p++) {
27 0 : if (!Py_ISSPACE(*p))
28 0 : Py_RETURN_FALSE;
29 : }
30 0 : Py_RETURN_TRUE;
31 : }
32 :
33 :
34 : PyDoc_STRVAR_shared(_Py_isalpha__doc__,
35 : "B.isalpha() -> bool\n\
36 : \n\
37 : Return True if all characters in B are alphabetic\n\
38 : and there is at least one character in B, False otherwise.");
39 :
40 : PyObject*
41 0 : _Py_bytes_isalpha(const char *cptr, Py_ssize_t len)
42 : {
43 0 : register const unsigned char *p
44 : = (unsigned char *) cptr;
45 : register const unsigned char *e;
46 :
47 : /* Shortcut for single character strings */
48 0 : if (len == 1 && Py_ISALPHA(*p))
49 0 : Py_RETURN_TRUE;
50 :
51 : /* Special case for empty strings */
52 0 : if (len == 0)
53 0 : Py_RETURN_FALSE;
54 :
55 0 : e = p + len;
56 0 : for (; p < e; p++) {
57 0 : if (!Py_ISALPHA(*p))
58 0 : Py_RETURN_FALSE;
59 : }
60 0 : Py_RETURN_TRUE;
61 : }
62 :
63 :
64 : PyDoc_STRVAR_shared(_Py_isalnum__doc__,
65 : "B.isalnum() -> bool\n\
66 : \n\
67 : Return True if all characters in B are alphanumeric\n\
68 : and there is at least one character in B, False otherwise.");
69 :
70 : PyObject*
71 0 : _Py_bytes_isalnum(const char *cptr, Py_ssize_t len)
72 : {
73 0 : register const unsigned char *p
74 : = (unsigned char *) cptr;
75 : register const unsigned char *e;
76 :
77 : /* Shortcut for single character strings */
78 0 : if (len == 1 && Py_ISALNUM(*p))
79 0 : Py_RETURN_TRUE;
80 :
81 : /* Special case for empty strings */
82 0 : if (len == 0)
83 0 : Py_RETURN_FALSE;
84 :
85 0 : e = p + len;
86 0 : for (; p < e; p++) {
87 0 : if (!Py_ISALNUM(*p))
88 0 : Py_RETURN_FALSE;
89 : }
90 0 : Py_RETURN_TRUE;
91 : }
92 :
93 :
94 : PyDoc_STRVAR_shared(_Py_isdigit__doc__,
95 : "B.isdigit() -> bool\n\
96 : \n\
97 : Return True if all characters in B are digits\n\
98 : and there is at least one character in B, False otherwise.");
99 :
100 : PyObject*
101 0 : _Py_bytes_isdigit(const char *cptr, Py_ssize_t len)
102 : {
103 0 : register const unsigned char *p
104 : = (unsigned char *) cptr;
105 : register const unsigned char *e;
106 :
107 : /* Shortcut for single character strings */
108 0 : if (len == 1 && Py_ISDIGIT(*p))
109 0 : Py_RETURN_TRUE;
110 :
111 : /* Special case for empty strings */
112 0 : if (len == 0)
113 0 : Py_RETURN_FALSE;
114 :
115 0 : e = p + len;
116 0 : for (; p < e; p++) {
117 0 : if (!Py_ISDIGIT(*p))
118 0 : Py_RETURN_FALSE;
119 : }
120 0 : Py_RETURN_TRUE;
121 : }
122 :
123 :
124 : PyDoc_STRVAR_shared(_Py_islower__doc__,
125 : "B.islower() -> bool\n\
126 : \n\
127 : Return True if all cased characters in B are lowercase and there is\n\
128 : at least one cased character in B, False otherwise.");
129 :
130 : PyObject*
131 0 : _Py_bytes_islower(const char *cptr, Py_ssize_t len)
132 : {
133 0 : 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 0 : if (len == 1)
140 0 : return PyBool_FromLong(Py_ISLOWER(*p));
141 :
142 : /* Special case for empty strings */
143 0 : if (len == 0)
144 0 : Py_RETURN_FALSE;
145 :
146 0 : e = p + len;
147 0 : cased = 0;
148 0 : for (; p < e; p++) {
149 0 : if (Py_ISUPPER(*p))
150 0 : Py_RETURN_FALSE;
151 0 : else if (!cased && Py_ISLOWER(*p))
152 0 : cased = 1;
153 : }
154 0 : return PyBool_FromLong(cased);
155 : }
156 :
157 :
158 : PyDoc_STRVAR_shared(_Py_isupper__doc__,
159 : "B.isupper() -> bool\n\
160 : \n\
161 : Return True if all cased characters in B are uppercase and there is\n\
162 : at least one cased character in B, False otherwise.");
163 :
164 : PyObject*
165 0 : _Py_bytes_isupper(const char *cptr, Py_ssize_t len)
166 : {
167 0 : 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 0 : if (len == 1)
174 0 : return PyBool_FromLong(Py_ISUPPER(*p));
175 :
176 : /* Special case for empty strings */
177 0 : if (len == 0)
178 0 : Py_RETURN_FALSE;
179 :
180 0 : e = p + len;
181 0 : cased = 0;
182 0 : for (; p < e; p++) {
183 0 : if (Py_ISLOWER(*p))
184 0 : Py_RETURN_FALSE;
185 0 : else if (!cased && Py_ISUPPER(*p))
186 0 : cased = 1;
187 : }
188 0 : return PyBool_FromLong(cased);
189 : }
190 :
191 :
192 : PyDoc_STRVAR_shared(_Py_istitle__doc__,
193 : "B.istitle() -> bool\n\
194 : \n\
195 : Return True if B is a titlecased string and there is at least one\n\
196 : character in B, i.e. uppercase characters may only follow uncased\n\
197 : characters and lowercase characters only cased ones. Return False\n\
198 : otherwise.");
199 :
200 : PyObject*
201 0 : _Py_bytes_istitle(const char *cptr, Py_ssize_t len)
202 : {
203 0 : 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 0 : if (len == 1)
210 0 : return PyBool_FromLong(Py_ISUPPER(*p));
211 :
212 : /* Special case for empty strings */
213 0 : if (len == 0)
214 0 : Py_RETURN_FALSE;
215 :
216 0 : e = p + len;
217 0 : cased = 0;
218 0 : previous_is_cased = 0;
219 0 : for (; p < e; p++) {
220 0 : register const unsigned char ch = *p;
221 :
222 0 : if (Py_ISUPPER(ch)) {
223 0 : if (previous_is_cased)
224 0 : Py_RETURN_FALSE;
225 0 : previous_is_cased = 1;
226 0 : cased = 1;
227 : }
228 0 : else if (Py_ISLOWER(ch)) {
229 0 : if (!previous_is_cased)
230 0 : Py_RETURN_FALSE;
231 0 : previous_is_cased = 1;
232 0 : cased = 1;
233 : }
234 : else
235 0 : previous_is_cased = 0;
236 : }
237 0 : return PyBool_FromLong(cased);
238 : }
239 :
240 :
241 : PyDoc_STRVAR_shared(_Py_lower__doc__,
242 : "B.lower() -> copy of B\n\
243 : \n\
244 : Return a copy of B with all ASCII characters converted to lowercase.");
245 :
246 : void
247 1 : _Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len)
248 : {
249 : Py_ssize_t i;
250 :
251 6 : for (i = 0; i < len; i++) {
252 5 : result[i] = Py_TOLOWER((unsigned char) cptr[i]);
253 : }
254 1 : }
255 :
256 :
257 : PyDoc_STRVAR_shared(_Py_upper__doc__,
258 : "B.upper() -> copy of B\n\
259 : \n\
260 : Return a copy of B with all ASCII characters converted to uppercase.");
261 :
262 : void
263 0 : _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len)
264 : {
265 : Py_ssize_t i;
266 :
267 0 : for (i = 0; i < len; i++) {
268 0 : result[i] = Py_TOUPPER((unsigned char) cptr[i]);
269 : }
270 0 : }
271 :
272 :
273 : PyDoc_STRVAR_shared(_Py_title__doc__,
274 : "B.title() -> copy of B\n\
275 : \n\
276 : Return a titlecased version of B, i.e. ASCII words start with uppercase\n\
277 : characters, all remaining cased characters have lowercase.");
278 :
279 : void
280 0 : _Py_bytes_title(char *result, char *s, Py_ssize_t len)
281 : {
282 : Py_ssize_t i;
283 0 : int previous_is_cased = 0;
284 :
285 0 : for (i = 0; i < len; i++) {
286 0 : int c = Py_CHARMASK(*s++);
287 0 : if (Py_ISLOWER(c)) {
288 0 : if (!previous_is_cased)
289 0 : c = Py_TOUPPER(c);
290 0 : previous_is_cased = 1;
291 0 : } else if (Py_ISUPPER(c)) {
292 0 : if (previous_is_cased)
293 0 : c = Py_TOLOWER(c);
294 0 : previous_is_cased = 1;
295 : } else
296 0 : previous_is_cased = 0;
297 0 : *result++ = c;
298 : }
299 0 : }
300 :
301 :
302 : PyDoc_STRVAR_shared(_Py_capitalize__doc__,
303 : "B.capitalize() -> copy of B\n\
304 : \n\
305 : Return a copy of B with only its first character capitalized (ASCII)\n\
306 : and the rest lower-cased.");
307 :
308 : void
309 0 : _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len)
310 : {
311 : Py_ssize_t i;
312 :
313 0 : if (0 < len) {
314 0 : int c = Py_CHARMASK(*s++);
315 0 : if (Py_ISLOWER(c))
316 0 : *result = Py_TOUPPER(c);
317 : else
318 0 : *result = c;
319 0 : result++;
320 : }
321 0 : for (i = 1; i < len; i++) {
322 0 : int c = Py_CHARMASK(*s++);
323 0 : if (Py_ISUPPER(c))
324 0 : *result = Py_TOLOWER(c);
325 : else
326 0 : *result = c;
327 0 : result++;
328 : }
329 0 : }
330 :
331 :
332 : PyDoc_STRVAR_shared(_Py_swapcase__doc__,
333 : "B.swapcase() -> copy of B\n\
334 : \n\
335 : Return a copy of B with uppercase ASCII characters converted\n\
336 : to lowercase ASCII and vice versa.");
337 :
338 : void
339 0 : _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len)
340 : {
341 : Py_ssize_t i;
342 :
343 0 : for (i = 0; i < len; i++) {
344 0 : int c = Py_CHARMASK(*s++);
345 0 : if (Py_ISLOWER(c)) {
346 0 : *result = Py_TOUPPER(c);
347 : }
348 0 : else if (Py_ISUPPER(c)) {
349 0 : *result = Py_TOLOWER(c);
350 : }
351 : else
352 0 : *result = c;
353 0 : result++;
354 : }
355 0 : }
356 :
357 :
358 : PyDoc_STRVAR_shared(_Py_maketrans__doc__,
359 : "B.maketrans(frm, to) -> translation table\n\
360 : \n\
361 : Return a translation table (a bytes object of length 256) suitable\n\
362 : for use in the bytes or bytearray translate method where each byte\n\
363 : in frm is mapped to the byte at the same position in to.\n\
364 : The bytes objects frm and to must be of the same length.");
365 :
366 : static Py_ssize_t
367 0 : _getbuffer(PyObject *obj, Py_buffer *view)
368 : {
369 0 : PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
370 :
371 0 : if (buffer == NULL || buffer->bf_getbuffer == NULL)
372 : {
373 0 : PyErr_Format(PyExc_TypeError,
374 : "Type %.100s doesn't support the buffer API",
375 0 : Py_TYPE(obj)->tp_name);
376 0 : return -1;
377 : }
378 :
379 0 : if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
380 0 : return -1;
381 0 : return view->len;
382 : }
383 :
384 : PyObject *
385 0 : _Py_bytes_maketrans(PyObject *args)
386 : {
387 0 : PyObject *frm, *to, *res = NULL;
388 : Py_buffer bfrm, bto;
389 : Py_ssize_t i;
390 : char *p;
391 :
392 0 : bfrm.len = -1;
393 0 : bto.len = -1;
394 :
395 0 : if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to))
396 0 : return NULL;
397 0 : if (_getbuffer(frm, &bfrm) < 0)
398 0 : return NULL;
399 0 : if (_getbuffer(to, &bto) < 0)
400 0 : goto done;
401 0 : if (bfrm.len != bto.len) {
402 0 : PyErr_Format(PyExc_ValueError,
403 : "maketrans arguments must have same length");
404 0 : goto done;
405 : }
406 0 : res = PyBytes_FromStringAndSize(NULL, 256);
407 0 : if (!res) {
408 0 : goto done;
409 : }
410 0 : p = PyBytes_AS_STRING(res);
411 0 : for (i = 0; i < 256; i++)
412 0 : p[i] = (char) i;
413 0 : for (i = 0; i < bfrm.len; i++) {
414 0 : p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i];
415 : }
416 :
417 : done:
418 0 : if (bfrm.len != -1)
419 0 : PyBuffer_Release(&bfrm);
420 0 : if (bto.len != -1)
421 0 : PyBuffer_Release(&bto);
422 0 : return res;
423 : }
|