NetSurf
ascii.h
Go to the documentation of this file.
1/*
2 * Copyright 2016 Michael Drake <tlsa@netsurf-browser.org>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * \file utils/ascii.h
21 * \brief Helpers for ASCII string handling.
22 *
23 * These helpers for string parsing will have the correct effect for parsing
24 * ASCII text (as used by most web specs), regardless of system locale.
25 */
26
27#ifndef _NETSURF_UTILS_ASCII_H_
28#define _NETSURF_UTILS_ASCII_H_
29
30#include <errno.h>
31#include <stdlib.h>
32#include <limits.h>
33
34/**
35 * Test whether a character is a whitespace character.
36 *
37 * \param[in] c Character to test.
38 * \return true iff `c` is whitespace, else false.
39 */
40static inline bool ascii_is_space(char c)
41{
42 return (c == ' ' || c == '\t' ||
43 c == '\n' || c == '\v' ||
44 c == '\f' || c == '\r');
45}
46
47/**
48 * Test whether a character is lower-case alphabetical.
49 *
50 * \param[in] c Character to test.
51 * \return true iff `c` is lower-case alphabetical, else false.
52 */
53static inline bool ascii_is_alpha_lower(char c)
54{
55 return (c >= 'a' && c <= 'z');
56}
57
58/**
59 * Test whether a character is upper-case alphabetical.
60 *
61 * \param[in] c Character to test.
62 * \return true iff `c` is upper-case alphabetical, else false.
63 */
64static inline bool ascii_is_alpha_upper(char c)
65{
66 return (c >= 'A' && c <= 'Z');
67}
68
69/**
70 * Test whether a character is alphabetical (upper or lower case).
71 *
72 * \param[in] c Character to test.
73 * \return true iff `c` is alphabetical, else false.
74 */
75static inline bool ascii_is_alpha(char c)
76{
78}
79
80/**
81 * Test whether a character is a decimal digit.
82 *
83 * \param[in] c Character to test.
84 * \return true iff `c` is a decimal digit, else false.
85 */
86static inline bool ascii_is_digit(char c)
87{
88 return (c >= '0' && c <= '9');
89}
90
91/**
92 * Test whether a character is a positive/negative numerical sign.
93 *
94 * \param[in] c Character to test.
95 * \return true iff `c` is a sign, else false.
96 */
97static inline bool ascii_is_sign(char c)
98{
99 return (c == '-' || c == '+');
100}
101
102/**
103 * Test whether a character is alphanumerical (upper or lower case).
104 *
105 * \param[in] c Character to test.
106 * \return true iff `c` is alphanumerical, else false.
107 */
108static inline bool ascii_is_alphanumerical(char c)
109{
110 return (ascii_is_alpha(c) || ascii_is_digit(c));
111}
112
113/**
114 * Test whether a character is 'a' to 'f' (lowercase).
115 *
116 * \param[in] c Character to test.
117 * \return true iff `c` is 'a' to 'f' (lowercase), else false.
118 */
119static inline bool ascii_is_af_lower(char c)
120{
121 return (c >= 'a' && c <= 'f');
122}
123
124/**
125 * Test whether a character is hexadecimal (lower case).
126 *
127 * \param[in] c Character to test.
128 * \return true iff `c` is hexadecimal, else false.
129 */
130static inline bool ascii_is_hex_lower(char c)
131{
132 return (ascii_is_digit(c) || ascii_is_af_lower(c));
133}
134
135/**
136 * Test whether a character is 'A' to 'F' (uppercase).
137 *
138 * \param[in] c Character to test.
139 * \return true iff `c` is 'A' to 'F' (uppercase), else false.
140 */
141static inline bool ascii_is_af_upper(char c)
142{
143 return (c >= 'A' && c <= 'F');
144}
145
146/**
147 * Test whether a character is hexadecimal (upper case).
148 *
149 * \param[in] c Character to test.
150 * \return true iff `c` is hexadecimal, else false.
151 */
152static inline bool ascii_is_hex_upper(char c)
153{
154 return (ascii_is_digit(c) || ascii_is_af_upper(c));
155}
156
157/**
158 * Test whether a character is hexadecimal (upper or lower case).
159 *
160 * \param[in] c Character to test.
161 * \return true iff `c` is hexadecimal, else false.
162 */
163static inline bool ascii_is_hex(char c)
164{
165 return (ascii_is_digit(c) ||
168}
169
170/**
171 * Convert a hexadecimal character to its value.
172 *
173 * \param[in] c Character to convert.
174 * \return value of character (0-15), or -256 if not a hexadecimal character.
175 */
176static inline int ascii_hex_to_value(char c)
177{
178 if (ascii_is_digit(c)) {
179 return c - '0';
180 } else if (ascii_is_af_lower(c)) {
181 return c - 'a' + 10;
182 } else if (ascii_is_af_upper(c)) {
183 return c - 'A' + 10;
184 }
185
186 /* Invalid hex */
187 return -256;
188}
189
190/**
191 * Converts two hexadecimal characters to a single number
192 *
193 * \param[in] c1 most significant hex digit.
194 * \param[in] c2 least significant hex digit.
195 * \return the total value of the two digit hex number (0-255),
196 * or -ve if input not hex.
197 */
198static inline int ascii_hex_to_value_2_chars(char c1, char c2)
199{
200 return 16 * ascii_hex_to_value(c1) + ascii_hex_to_value(c2);
201}
202
203/**
204 * Convert an upper case character to lower case.
205 *
206 * If the given character is not upper case alphabetical, it is returned
207 * unchanged.
208 *
209 * \param[in] c Character to convert.
210 * \return lower case conversion of `c` else `c`.
211 */
212static inline char ascii_to_lower(char c)
213{
214 return (ascii_is_alpha_upper(c)) ? (c + 'a' - 'A') : c;
215}
216
217/**
218 * Convert a lower case character to upper case.
219 *
220 * If the given character is not lower case alphabetical, it is returned
221 * unchanged.
222 *
223 * \param[in] c Character to convert.
224 * \return upper case conversion of `c` else `c`.
225 */
226static inline char ascii_to_upper(char c)
227{
228 return (ascii_is_alpha_lower(c)) ? (c + 'A' - 'a') : c;
229}
230
231/**
232 * Count consecutive lower case alphabetical characters in string.
233 *
234 * \param[in] str String to count characters in.
235 * \return number of consecutive lower case characters at start of `str`.
236 */
237static inline size_t ascii_count_alpha_lower(const char *str)
238{
239 size_t count = 0;
240 while (ascii_is_alpha_lower(*(str++))) {
241 count++;
242 }
243 return count;
244}
245
246/**
247 * Count consecutive upper case alphabetical characters in string.
248 *
249 * \param[in] str String to count characters in.
250 * \return number of consecutive upper case characters at start of `str`.
251 */
252static inline size_t ascii_count_alpha_upper(const char *str)
253{
254 size_t count = 0;
255 while (ascii_is_alpha_upper(*(str++))) {
256 count++;
257 }
258 return count;
259}
260
261/**
262 * Count consecutive alphabetical characters in string (upper or lower case).
263 *
264 * \param[in] str String to count characters in.
265 * \return number of consecutive alphabetical characters at start of `str`.
266 */
267static inline size_t ascii_count_alpha(const char *str)
268{
269 size_t count = 0;
270 while (ascii_is_alpha(*(str++))) {
271 count++;
272 }
273 return count;
274}
275
276/**
277 * Count consecutive decial digit characters in string.
278 *
279 * \param[in] str String to count characters in.
280 * \return number of consecutive decimal digit characters at start of `str`.
281 */
282static inline size_t ascii_count_digit(const char *str)
283{
284 size_t count = 0;
285 while (ascii_is_digit(*(str++))) {
286 count++;
287 }
288 return count;
289}
290
291/**
292 * Count consecutive characters either decimal digit or colon in string.
293 *
294 * \param[in] str String to count characters in.
295 * \return number of consecutive decimal or ':' characters at start of `str`.
296 */
297static inline size_t ascii_count_digit_or_colon(const char *str)
298{
299 size_t count = 0;
300 while (ascii_is_digit(*str) || *str == ':') {
301 count++;
302 str++;
303 }
304 return count;
305}
306
307/**
308 * Test for string equality (case insensitive).
309 *
310 * \param[in] s1 First string to compare.
311 * \param[in] s2 Second string to compare.
312 * \return true iff strings are equivalent, else false.
313 */
315 const char *s1, const char *s2)
316{
317 while (*s1 != '\0') {
318 if (ascii_to_lower(*s1) != ascii_to_lower(*s2)) {
319 break;
320 }
321 s1++;
322 s2++;
323 }
324 return (ascii_to_lower(*s1) == ascii_to_lower(*s2));
325}
326
327/**
328 * Test for string equality (case sensitive).
329 *
330 * \param[in] s1 First string to compare.
331 * \param[in] s2 Second string to compare.
332 * \return true iff strings are equal, else false.
333 */
334static inline bool ascii_strings_equal(
335 const char *s1, const char *s2)
336{
337 while (*s1 != '\0') {
338 if (*s1 != *s2) {
339 break;
340 }
341 s1++;
342 s2++;
343 }
344 return (*s1 == *s2);
345}
346
347/**
348 * Count consecutive equal ascii characters (case insensitive).
349 *
350 * \param[in] s1 First string to compare.
351 * \param[in] s2 Second string to compare.
352 * \return number of equivalent characters.
353 */
355 const char *s1, const char *s2)
356{
357 const char *s = s1;
358 while (*s1 != '\0') {
359 if (ascii_to_lower(*s1) != ascii_to_lower(*s2)) {
360 break;
361 }
362 s1++;
363 s2++;
364 }
365 return s1 - s;
366}
367
368/**
369 * Count consecutive equal ascii characters (case sensitive).
370 *
371 * \param[in] s1 First string to compare.
372 * \param[in] s2 Second string to compare.
373 * \return number of equal characters.
374 */
375static inline size_t ascii_strings_count_equal(
376 const char *s1, const char *s2)
377{
378 const char *s = s1;
379 while (*s1 != '\0') {
380 if (*s1 != *s2) {
381 break;
382 }
383 s1++;
384 s2++;
385 }
386 return s1 - s;
387}
388
389/**
390 * Parse an int out of a string.
391 *
392 * \param[in] str String to parse integer out of.
393 * \param[out] res Returns parsed integer.
394 * \return The number of characters consumed in `str`.
395 * Returning 0 indicates failure to parse an integer out of the string.
396 */
397static inline size_t ascii_string_to_int(const char *str, int *res)
398{
399 char *end = NULL;
400 long long temp = strtoll(str, &end, 10);
401
402 if (end == str || errno == ERANGE ||
403 temp < INT_MIN || temp > INT_MAX) {
404 return 0;
405 }
406
407 *res = temp;
408 return end - str;
409}
410
411#endif
static bool ascii_is_hex_lower(char c)
Test whether a character is hexadecimal (lower case).
Definition: ascii.h:130
static size_t ascii_count_alpha_lower(const char *str)
Count consecutive lower case alphabetical characters in string.
Definition: ascii.h:237
static char ascii_to_lower(char c)
Convert an upper case character to lower case.
Definition: ascii.h:212
static char ascii_to_upper(char c)
Convert a lower case character to upper case.
Definition: ascii.h:226
static size_t ascii_count_alpha(const char *str)
Count consecutive alphabetical characters in string (upper or lower case).
Definition: ascii.h:267
static int ascii_hex_to_value_2_chars(char c1, char c2)
Converts two hexadecimal characters to a single number.
Definition: ascii.h:198
static size_t ascii_string_to_int(const char *str, int *res)
Parse an int out of a string.
Definition: ascii.h:397
static size_t ascii_count_digit_or_colon(const char *str)
Count consecutive characters either decimal digit or colon in string.
Definition: ascii.h:297
static bool ascii_is_sign(char c)
Test whether a character is a positive/negative numerical sign.
Definition: ascii.h:97
static bool ascii_is_hex_upper(char c)
Test whether a character is hexadecimal (upper case).
Definition: ascii.h:152
static size_t ascii_count_digit(const char *str)
Count consecutive decial digit characters in string.
Definition: ascii.h:282
static bool ascii_is_alpha(char c)
Test whether a character is alphabetical (upper or lower case).
Definition: ascii.h:75
static bool ascii_is_af_lower(char c)
Test whether a character is 'a' to 'f' (lowercase).
Definition: ascii.h:119
static bool ascii_is_alpha_lower(char c)
Test whether a character is lower-case alphabetical.
Definition: ascii.h:53
static int ascii_hex_to_value(char c)
Convert a hexadecimal character to its value.
Definition: ascii.h:176
static bool ascii_is_space(char c)
Test whether a character is a whitespace character.
Definition: ascii.h:40
static bool ascii_is_alpha_upper(char c)
Test whether a character is upper-case alphabetical.
Definition: ascii.h:64
static bool ascii_is_digit(char c)
Test whether a character is a decimal digit.
Definition: ascii.h:86
static size_t ascii_strings_count_equal_caseless(const char *s1, const char *s2)
Count consecutive equal ascii characters (case insensitive).
Definition: ascii.h:354
static bool ascii_is_af_upper(char c)
Test whether a character is 'A' to 'F' (uppercase).
Definition: ascii.h:141
static size_t ascii_count_alpha_upper(const char *str)
Count consecutive upper case alphabetical characters in string.
Definition: ascii.h:252
static bool ascii_strings_equal_caseless(const char *s1, const char *s2)
Test for string equality (case insensitive).
Definition: ascii.h:314
static bool ascii_is_hex(char c)
Test whether a character is hexadecimal (upper or lower case).
Definition: ascii.h:163
static size_t ascii_strings_count_equal(const char *s1, const char *s2)
Count consecutive equal ascii characters (case sensitive).
Definition: ascii.h:375
static bool ascii_is_alphanumerical(char c)
Test whether a character is alphanumerical (upper or lower case).
Definition: ascii.h:108
static bool ascii_strings_equal(const char *s1, const char *s2)
Test for string equality (case sensitive).
Definition: ascii.h:334
static uint32_t count(const http_directive *list, lwc_string *key)
long long int strtoll(const char *nptr, char **endptr, int base)
Definition: os3support.c:198