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 /src/microhttpd/mhd_str.c | |
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
Diffstat (limited to 'src/microhttpd/mhd_str.c')
-rw-r--r-- | src/microhttpd/mhd_str.c | 104 |
1 files changed, 104 insertions, 0 deletions
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 | } | ||