diff options
Diffstat (limited to 'src/microhttpd/mhd_str.c')
-rw-r--r-- | src/microhttpd/mhd_str.c | 103 |
1 files changed, 100 insertions, 3 deletions
diff --git a/src/microhttpd/mhd_str.c b/src/microhttpd/mhd_str.c index c0f1d271..8e6ff92e 100644 --- a/src/microhttpd/mhd_str.c +++ b/src/microhttpd/mhd_str.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of libmicrohttpd | 2 | This file is part of libmicrohttpd |
3 | Copyright (C) 2015 Karlson2k (Evgeny Grin) | 3 | Copyright (C) 2015, 2016 Karlson2k (Evgeny Grin) |
4 | 4 | ||
5 | This library is free software; you can redistribute it and/or | 5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public | 6 | modify it under the terms of the GNU Lesser General Public |
@@ -25,14 +25,25 @@ | |||
25 | 25 | ||
26 | #include "mhd_str.h" | 26 | #include "mhd_str.h" |
27 | 27 | ||
28 | #include "mhd_options.h" | ||
29 | |||
30 | #ifdef HAVE_STDBOOL_H | 28 | #ifdef HAVE_STDBOOL_H |
31 | #include <stdbool.h> | 29 | #include <stdbool.h> |
32 | #endif | 30 | #endif |
33 | 31 | ||
34 | #include "mhd_limits.h" | 32 | #include "mhd_limits.h" |
35 | 33 | ||
34 | #ifdef MHD_FAVOR_SMALL_CODE | ||
35 | #ifdef _MHD_inline | ||
36 | #undef _MHD_inline | ||
37 | #endif /* _MHD_inline */ | ||
38 | /* Do not force inlining and do not use macro functions, use normal static | ||
39 | functions instead. | ||
40 | This may give more flexibility for size optimizations. */ | ||
41 | #define _MHD_inline static | ||
42 | #ifndef INLINE_FUNC | ||
43 | #define INLINE_FUNC 1 | ||
44 | #endif /* !INLINE_FUNC */ | ||
45 | #endif /* MHD_FAVOR_SMALL_CODE */ | ||
46 | |||
36 | /* | 47 | /* |
37 | * Block of functions/macros that use US-ASCII charset as required by HTTP | 48 | * Block of functions/macros that use US-ASCII charset as required by HTTP |
38 | * standards. Not affected by current locale settings. | 49 | * standards. Not affected by current locale settings. |
@@ -136,6 +147,20 @@ toasciiupper (char c) | |||
136 | } | 147 | } |
137 | 148 | ||
138 | /** | 149 | /** |
150 | * Convert US-ASCII decimal digit to its value. | ||
151 | * @param c character to convert | ||
152 | * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit | ||
153 | */ | ||
154 | _MHD_inline int | ||
155 | todigitvalue (char c) | ||
156 | { | ||
157 | if (isasciidigit (c)) | ||
158 | return (unsigned char)(c - '0'); | ||
159 | |||
160 | return -1; | ||
161 | } | ||
162 | |||
163 | /** | ||
139 | * Convert US-ASCII hexadecimal digit to its value. | 164 | * Convert US-ASCII hexadecimal digit to its value. |
140 | * @param c character to convert | 165 | * @param c character to convert |
141 | * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit | 166 | * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit |
@@ -225,6 +250,13 @@ toxdigitvalue (char c) | |||
225 | #define toasciiupper(c) ((isasciilower(c)) ? (((char)(c)) - 'a' + 'A') : ((char)(c))) | 250 | #define toasciiupper(c) ((isasciilower(c)) ? (((char)(c)) - 'a' + 'A') : ((char)(c))) |
226 | 251 | ||
227 | /** | 252 | /** |
253 | * Convert US-ASCII decimal digit to its value. | ||
254 | * @param c character to convert | ||
255 | * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit | ||
256 | */ | ||
257 | #define todigitvalue(c) (isasciidigit(c) ? (int)(((char)(c)) - '0') : (int)(-1)) | ||
258 | |||
259 | /** | ||
228 | * Convert US-ASCII hexadecimal digit to its value. | 260 | * Convert US-ASCII hexadecimal digit to its value. |
229 | * @param c character to convert | 261 | * @param c character to convert |
230 | * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit | 262 | * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit |
@@ -236,6 +268,7 @@ toxdigitvalue (char c) | |||
236 | (int)(((unsigned char)(c)) - 'a' + 10) : (int)(-1) ))) | 268 | (int)(((unsigned char)(c)) - 'a' + 10) : (int)(-1) ))) |
237 | #endif /* !INLINE_FUNC */ | 269 | #endif /* !INLINE_FUNC */ |
238 | 270 | ||
271 | #ifndef MHD_FAVOR_SMALL_CODE | ||
239 | /** | 272 | /** |
240 | * Check two string for equality, ignoring case of US-ASCII letters. | 273 | * Check two string for equality, ignoring case of US-ASCII letters. |
241 | * @param str1 first string to compare | 274 | * @param str1 first string to compare |
@@ -256,6 +289,7 @@ MHD_str_equal_caseless_ (const char * str1, const char * str2) | |||
256 | } | 289 | } |
257 | return 0 == (*str2); | 290 | return 0 == (*str2); |
258 | } | 291 | } |
292 | #endif /* ! MHD_FAVOR_SMALL_CODE */ | ||
259 | 293 | ||
260 | 294 | ||
261 | /** | 295 | /** |
@@ -284,6 +318,9 @@ MHD_str_equal_caseless_n_ (const char * const str1, const char * const str2, siz | |||
284 | return !0; | 318 | return !0; |
285 | } | 319 | } |
286 | 320 | ||
321 | #ifndef MHD_FAVOR_SMALL_CODE | ||
322 | /* Use individual function for each case */ | ||
323 | |||
287 | /** | 324 | /** |
288 | * Convert decimal US-ASCII digits in string to number in uint64_t. | 325 | * Convert decimal US-ASCII digits in string to number in uint64_t. |
289 | * Conversion stopped at first non-digit character. | 326 | * Conversion stopped at first non-digit character. |
@@ -596,3 +633,63 @@ MHD_strx_to_uint64_n_ (const char * str, size_t maxlen, uint64_t * out_val) | |||
596 | *out_val = res; | 633 | *out_val = res; |
597 | return i; | 634 | return i; |
598 | } | 635 | } |
636 | |||
637 | #else /* MHD_FAVOR_SMALL_CODE */ | ||
638 | |||
639 | /** | ||
640 | * Generic function for converting not more then @a maxlen | ||
641 | * hexadecimal or decimal US-ASCII digits in string to number. | ||
642 | * Conversion stopped at first non-digit character or after @a maxlen | ||
643 | * digits. | ||
644 | * To be used only within macro. | ||
645 | * @param str the string to convert | ||
646 | * @param maxlen the maximum number of characters to process | ||
647 | * @param out_val the pointer to variable to store result of conversion | ||
648 | * @param val_size the size of variable pointed by @a out_val, in bytes, 4 or 8 | ||
649 | * @param max_val the maximum decoded number | ||
650 | * @param base the numeric base, 10 or 16 | ||
651 | * @return non-zero number of characters processed on succeed, | ||
652 | * zero if no digit is found, resulting value is larger | ||
653 | * then @max_val, @val_size is not 16/32 or @a out_val is NULL | ||
654 | */ | ||
655 | size_t | ||
656 | MHD_str_to_uvalue_n_ (const char * str, size_t maxlen, | ||
657 | void * out_val, size_t val_size, uint64_t max_val, int base) | ||
658 | { | ||
659 | size_t i; | ||
660 | uint64_t res; | ||
661 | int digit; | ||
662 | const uint64_t max_v_div_b = max_val / base; | ||
663 | const uint64_t max_v_mod_b = max_val % base; | ||
664 | /* 'digit->value' must be function, not macro */ | ||
665 | int (*const dfunc)(char) = (base == 16) ? | ||
666 | toxdigitvalue : todigitvalue; | ||
667 | if ( !str || !out_val || | ||
668 | (base != 16 && base != 10) ) | ||
669 | return 0; | ||
670 | |||
671 | res = 0; | ||
672 | i = 0; | ||
673 | while (maxlen > i && 0 <= (digit = dfunc (str[i]))) | ||
674 | { | ||
675 | if ( ((max_v_div_b) < res) || | ||
676 | ((max_v_div_b) == res && (max_v_mod_b) < (uint64_t)digit) ) | ||
677 | return 0; | ||
678 | |||
679 | res *= base; | ||
680 | res += digit; | ||
681 | i++; | ||
682 | } | ||
683 | |||
684 | if (i) | ||
685 | { | ||
686 | if (8 == val_size) | ||
687 | *(uint64_t*)out_val = res; | ||
688 | else if (4 == val_size) | ||
689 | *(uint32_t*)out_val = (uint32_t)res; | ||
690 | else | ||
691 | return 0; | ||
692 | } | ||
693 | return i; | ||
694 | } | ||
695 | #endif /* MHD_FAVOR_SMALL_CODE */ | ||