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*
_Py_bytes_isspace(const char * cptr,Py_ssize_t len)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 */
18     if (len == 1 && Py_ISSPACE(*p))
19         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++) {
27         if (!Py_ISSPACE(*p))
28             Py_RETURN_FALSE;
29     }
30     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*
_Py_bytes_isalpha(const char * cptr,Py_ssize_t len)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 */
48     if (len == 1 && Py_ISALPHA(*p))
49         Py_RETURN_TRUE;
50 
51     /* Special case for empty strings */
52     if (len == 0)
53         Py_RETURN_FALSE;
54 
55     e = p + len;
56     for (; p < e; p++) {
57         if (!Py_ISALPHA(*p))
58             Py_RETURN_FALSE;
59     }
60     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*
_Py_bytes_isalnum(const char * cptr,Py_ssize_t len)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 */
78     if (len == 1 && Py_ISALNUM(*p))
79         Py_RETURN_TRUE;
80 
81     /* Special case for empty strings */
82     if (len == 0)
83         Py_RETURN_FALSE;
84 
85     e = p + len;
86     for (; p < e; p++) {
87         if (!Py_ISALNUM(*p))
88             Py_RETURN_FALSE;
89     }
90     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*
_Py_bytes_isdigit(const char * cptr,Py_ssize_t len)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 */
108     if (len == 1 && Py_ISDIGIT(*p))
109         Py_RETURN_TRUE;
110 
111     /* Special case for empty strings */
112     if (len == 0)
113         Py_RETURN_FALSE;
114 
115     e = p + len;
116     for (; p < e; p++) {
117         if (!Py_ISDIGIT(*p))
118             Py_RETURN_FALSE;
119     }
120     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*
_Py_bytes_islower(const char * cptr,Py_ssize_t len)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)
140         return PyBool_FromLong(Py_ISLOWER(*p));
141 
142     /* Special case for empty strings */
143     if (len == 0)
144         Py_RETURN_FALSE;
145 
146     e = p + len;
147     cased = 0;
148     for (; p < e; p++) {
149         if (Py_ISUPPER(*p))
150             Py_RETURN_FALSE;
151         else if (!cased && Py_ISLOWER(*p))
152             cased = 1;
153     }
154     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*
_Py_bytes_isupper(const char * cptr,Py_ssize_t len)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)
174         return PyBool_FromLong(Py_ISUPPER(*p));
175 
176     /* Special case for empty strings */
177     if (len == 0)
178         Py_RETURN_FALSE;
179 
180     e = p + len;
181     cased = 0;
182     for (; p < e; p++) {
183         if (Py_ISLOWER(*p))
184             Py_RETURN_FALSE;
185         else if (!cased && Py_ISUPPER(*p))
186             cased = 1;
187     }
188     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*
_Py_bytes_istitle(const char * cptr,Py_ssize_t len)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)
210         return PyBool_FromLong(Py_ISUPPER(*p));
211 
212     /* Special case for empty strings */
213     if (len == 0)
214         Py_RETURN_FALSE;
215 
216     e = p + len;
217     cased = 0;
218     previous_is_cased = 0;
219     for (; p < e; p++) {
220         register const unsigned char ch = *p;
221 
222         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;
236     }
237     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
_Py_bytes_lower(char * result,const char * cptr,Py_ssize_t len)247 _Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len)
248 {
249         Py_ssize_t i;
250 
251         /*
252         newobj = PyString_FromStringAndSize(NULL, len);
253         if (!newobj)
254                 return NULL;
255 
256         s = PyString_AS_STRING(newobj);
257         */
258 
259         Py_MEMCPY(result, cptr, len);
260 
261         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         }
266 }
267 
268 
269 PyDoc_STRVAR_shared(_Py_upper__doc__,
270 "B.upper() -> copy of B\n\
271 \n\
272 Return a copy of B with all ASCII characters converted to uppercase.");
273 
274 void
_Py_bytes_upper(char * result,const char * cptr,Py_ssize_t len)275 _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len)
276 {
277         Py_ssize_t i;
278 
279         /*
280         newobj = PyString_FromStringAndSize(NULL, len);
281         if (!newobj)
282                 return NULL;
283 
284         s = PyString_AS_STRING(newobj);
285         */
286 
287         Py_MEMCPY(result, cptr, len);
288 
289         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         }
294 }
295 
296 
297 PyDoc_STRVAR_shared(_Py_title__doc__,
298 "B.title() -> copy of B\n\
299 \n\
300 Return a titlecased version of B, i.e. ASCII words start with uppercase\n\
301 characters, all remaining cased characters have lowercase.");
302 
303 void
_Py_bytes_title(char * result,char * s,Py_ssize_t len)304 _Py_bytes_title(char *result, char *s, Py_ssize_t len)
305 {
306         Py_ssize_t i;
307         int previous_is_cased = 0;
308 
309         /*
310         newobj = PyString_FromStringAndSize(NULL, len);
311         if (newobj == NULL)
312                 return NULL;
313         s_new = PyString_AsString(newobj);
314         */
315         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         }
329 }
330 
331 
332 PyDoc_STRVAR_shared(_Py_capitalize__doc__,
333 "B.capitalize() -> copy of B\n\
334 \n\
335 Return a copy of B with only its first character capitalized (ASCII)\n\
336 and the rest lower-cased.");
337 
338 void
_Py_bytes_capitalize(char * result,char * s,Py_ssize_t len)339 _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len)
340 {
341         Py_ssize_t i;
342 
343         /*
344         newobj = PyString_FromStringAndSize(NULL, len);
345         if (newobj == NULL)
346                 return NULL;
347         s_new = PyString_AsString(newobj);
348         */
349         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         }
365 }
366 
367 
368 PyDoc_STRVAR_shared(_Py_swapcase__doc__,
369 "B.swapcase() -> copy of B\n\
370 \n\
371 Return a copy of B with uppercase ASCII characters converted\n\
372 to lowercase ASCII and vice versa.");
373 
374 void
_Py_bytes_swapcase(char * result,char * s,Py_ssize_t len)375 _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len)
376 {
377         Py_ssize_t i;
378 
379         /*
380         newobj = PyString_FromStringAndSize(NULL, len);
381         if (newobj == NULL)
382                 return NULL;
383         s_new = PyString_AsString(newobj);
384         */
385         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         }
397 }
398 
399