aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-04-11 20:07:36 +0000
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-04-11 20:07:36 +0000
commitaff8b7214bae150c5aac8544396cd938ebc21e47 (patch)
tree2bd24ef20561e51d9f1fc1b760fdedec52c20a25
parentdc1eb9a9d79d4272d8d29348ca37a10634eb7e8f (diff)
downloadlibmicrohttpd-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.h4
-rw-r--r--src/microhttpd/mhd_str.c104
-rw-r--r--src/microhttpd/mhd_str.h35
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 */
246int
247MHD_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 */
297int
298MHD_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 */
74int
75MHD_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 */
92int
93MHD_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 */