diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-04-11 20:07:36 +0000 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-04-11 20:07:36 +0000 |
commit | aff8b7214bae150c5aac8544396cd938ebc21e47 (patch) | |
tree | 2bd24ef20561e51d9f1fc1b760fdedec52c20a25 | |
parent | dc1eb9a9d79d4272d8d29348ca37a10634eb7e8f (diff) | |
download | libmicrohttpd-aff8b7214bae150c5aac8544396cd938ebc21e47.tar.gz libmicrohttpd-aff8b7214bae150c5aac8544396cd938ebc21e47.zip |
mhd_str: added MHD_str_to_uint64_() and MHD_str_to_uint64_n_() functions for US-ASCII-only
operations, independently on locale
-rw-r--r-- | src/microhttpd/mhd_limits.h | 4 | ||||
-rw-r--r-- | src/microhttpd/mhd_str.c | 104 | ||||
-rw-r--r-- | src/microhttpd/mhd_str.h | 35 |
3 files changed, 143 insertions, 0 deletions
diff --git a/src/microhttpd/mhd_limits.h b/src/microhttpd/mhd_limits.h index 5ce2f9c4..c8eff094 100644 --- a/src/microhttpd/mhd_limits.h +++ b/src/microhttpd/mhd_limits.h | |||
@@ -44,6 +44,10 @@ | |||
44 | #define INT32_MAX ((int32_t)0x7FFFFFFF) | 44 | #define INT32_MAX ((int32_t)0x7FFFFFFF) |
45 | #endif /* !INT32_MAX */ | 45 | #endif /* !INT32_MAX */ |
46 | 46 | ||
47 | #ifndef UINT64_MAX | ||
48 | #define UINT64_MAX ((uint64_t)0xFFFFFFFFFFFFFFFF) | ||
49 | #endif /* !INT32_MAX */ | ||
50 | |||
47 | #ifndef SIZE_MAX | 51 | #ifndef SIZE_MAX |
48 | #define SIZE_MAX ((size_t) ~((size_t)0)) | 52 | #define SIZE_MAX ((size_t) ~((size_t)0)) |
49 | #endif /* !SIZE_MAX */ | 53 | #endif /* !SIZE_MAX */ |
diff --git a/src/microhttpd/mhd_str.c b/src/microhttpd/mhd_str.c index 1e9154ba..61e5604b 100644 --- a/src/microhttpd/mhd_str.c +++ b/src/microhttpd/mhd_str.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <stdbool.h> | 31 | #include <stdbool.h> |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | #include "mhd_limits.h" | ||
35 | |||
34 | /* | 36 | /* |
35 | * Block of functions/macros that use US-ASCII charset as required by HTTP | 37 | * Block of functions/macros that use US-ASCII charset as required by HTTP |
36 | * standards. Not affected by current locale settings. | 38 | * standards. Not affected by current locale settings. |
@@ -229,3 +231,105 @@ MHD_str_equal_caseless_n_ (const char * const str1, const char * const str2, siz | |||
229 | } | 231 | } |
230 | return !0; | 232 | return !0; |
231 | } | 233 | } |
234 | |||
235 | /** | ||
236 | * Convert decimal US-ASCII digits in string to number in uint64_t. | ||
237 | * Conversion stopped at first non-digit character. | ||
238 | * @param str string to convert | ||
239 | * @param out_val pointer to uint64_t to store result of conversion | ||
240 | * @param next_char pointer to store pointer to character next to last | ||
241 | * converted digit, ignored if NULL | ||
242 | * @return non-zero if conversion succeed; zero if no digit is found, | ||
243 | * value is larger then possible to store in uint64_t or | ||
244 | * @a out_val or @a str is NULL | ||
245 | */ | ||
246 | int | ||
247 | MHD_str_to_uint64_ (const char * str, uint64_t * out_val, const char ** next_char) | ||
248 | { | ||
249 | uint64_t res; | ||
250 | if (!str || !isasciidigit(str[0])) | ||
251 | { | ||
252 | if (next_char) | ||
253 | *next_char = str; | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | res = 0; | ||
258 | do | ||
259 | { | ||
260 | const int digit = str[0] - '0'; | ||
261 | if ( (res < (UINT64_MAX / 10)) || | ||
262 | (res == (UINT64_MAX / 10) && digit <= (UINT64_MAX % 10)) ) | ||
263 | { | ||
264 | res *= 10; | ||
265 | res += digit; | ||
266 | } | ||
267 | else | ||
268 | { | ||
269 | if (next_char) | ||
270 | *next_char = str; | ||
271 | return 0; | ||
272 | } | ||
273 | str++; | ||
274 | } while (isasciidigit (str[0])); | ||
275 | |||
276 | *out_val = res; | ||
277 | if (next_char) | ||
278 | *next_char = str; | ||
279 | |||
280 | return !0; | ||
281 | } | ||
282 | |||
283 | |||
284 | /** | ||
285 | * Convert not more then @a maxlen decimal US-ASCII digits in string to | ||
286 | * number in uint64_t. | ||
287 | * Conversion stopped at first non-digit character or after @a maxlen | ||
288 | * digits. | ||
289 | * @param str string to convert | ||
290 | * @param out_val pointer to uint64_t to store result of conversion | ||
291 | * @param next_char pointer to store pointer to character next to last | ||
292 | * converted digit, ignored if NULL | ||
293 | * @return non-zero if conversion succeed; zero if no digit is found, | ||
294 | * value is larger then possible to store in uint64_t or | ||
295 | * @a out_val is NULL | ||
296 | */ | ||
297 | int | ||
298 | MHD_str_to_uint64_n_ (const char * str, size_t maxlen, uint64_t * out_val, | ||
299 | const char ** next_char) | ||
300 | { | ||
301 | uint64_t res; | ||
302 | size_t i; | ||
303 | if (!str || !maxlen || !isasciidigit (str[0])) | ||
304 | { | ||
305 | if (next_char) | ||
306 | *next_char = str; | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | res = 0; | ||
311 | i = 0; | ||
312 | do | ||
313 | { | ||
314 | const int digit = str[i] - '0'; | ||
315 | if ( (res < (UINT64_MAX / 10)) || | ||
316 | (res == (UINT64_MAX / 10) && digit <= (UINT64_MAX % 10)) ) | ||
317 | { | ||
318 | res *= 10; | ||
319 | res += digit; | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | if (next_char) | ||
324 | *next_char = str + i; | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | } while(i < maxlen && isasciidigit(str[i])); | ||
329 | |||
330 | *out_val = res; | ||
331 | if (next_char) | ||
332 | *next_char = str + i; | ||
333 | |||
334 | return !0; | ||
335 | } | ||
diff --git a/src/microhttpd/mhd_str.h b/src/microhttpd/mhd_str.h index 6975d6b8..22d09cff 100644 --- a/src/microhttpd/mhd_str.h +++ b/src/microhttpd/mhd_str.h | |||
@@ -60,4 +60,39 @@ MHD_str_equal_caseless_n_ (const char * const str1, | |||
60 | const char * const str2, | 60 | const char * const str2, |
61 | size_t maxlen); | 61 | size_t maxlen); |
62 | 62 | ||
63 | /** | ||
64 | * Convert decimal US-ASCII digits in string to number in uint64_t. | ||
65 | * Conversion stopped at first non-digit character. | ||
66 | * @param str string to convert | ||
67 | * @param out_val pointer to uint64_t to store result of conversion | ||
68 | * @param next_char pointer to store pointer to character next to last | ||
69 | * converted digit, ignored if NULL | ||
70 | * @return non-zero if conversion succeed; zero if no digit is found, | ||
71 | * value is larger then possible to store in uint64_t or | ||
72 | * @a out_val is NULL | ||
73 | */ | ||
74 | int | ||
75 | MHD_str_to_uint64_ (const char * str, | ||
76 | uint64_t * out_val, | ||
77 | const char ** next_char); | ||
78 | |||
79 | /** | ||
80 | * Convert not more then @a maxlen decimal US-ASCII digits in string to | ||
81 | * number in uint64_t. | ||
82 | * Conversion stopped at first non-digit character or after @a maxlen | ||
83 | * digits. | ||
84 | * @param str string to convert | ||
85 | * @param out_val pointer to uint64_t to store result of conversion | ||
86 | * @param next_char pointer to store pointer to character next to last | ||
87 | * converted digit, ignored if NULL | ||
88 | * @return non-zero if conversion succeed; zero if no digit is found, | ||
89 | * value is larger then possible to store in uint64_t or | ||
90 | * @a out_val is NULL | ||
91 | */ | ||
92 | int | ||
93 | MHD_str_to_uint64_n_ (const char * str, | ||
94 | size_t maxlen, | ||
95 | uint64_t * out_val, | ||
96 | const char ** next_char); | ||
97 | |||
63 | #endif /* MHD_STR_H */ | 98 | #endif /* MHD_STR_H */ |