diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-07-23 18:55:09 +0000 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-07-23 18:55:09 +0000 |
commit | 43bb6196b0d76d04afca8dd478a47f38352b6e29 (patch) | |
tree | 19d5c9f9a016bdb94e96f0503e74a982f56af080 /src | |
parent | abdd48c5f2ca74db2501a4e52245dfc8bd470710 (diff) | |
download | libmicrohttpd-43bb6196b0d76d04afca8dd478a47f38352b6e29.tar.gz libmicrohttpd-43bb6196b0d76d04afca8dd478a47f38352b6e29.zip |
Added MHD_FAVOR_FAST_CODE and MHD_FAVOR_SMALL_CODE automatic macros.
Macros can be forced by external define.
Added versions of mhd_str functions for smaller resulting code.
Diffstat (limited to 'src')
-rw-r--r-- | src/include/mhd_options.h | 21 | ||||
-rw-r--r-- | src/microhttpd/mhd_str.c | 103 | ||||
-rw-r--r-- | src/microhttpd/mhd_str.h | 69 |
3 files changed, 189 insertions, 4 deletions
diff --git a/src/include/mhd_options.h b/src/include/mhd_options.h index 3541c4b8..2e798ebf 100644 --- a/src/include/mhd_options.h +++ b/src/include/mhd_options.h | |||
@@ -93,4 +93,25 @@ | |||
93 | #define __STDC_WANT_LIB_EXT1__ 1 | 93 | #define __STDC_WANT_LIB_EXT1__ 1 |
94 | #endif /* HAVE_C11_GMTIME_S */ | 94 | #endif /* HAVE_C11_GMTIME_S */ |
95 | 95 | ||
96 | #if defined(MHD_FAVOR_FAST_CODE) && defined(MHD_FAVOR_SMALL_CODE) | ||
97 | #error MHD_FAVOR_FAST_CODE and MHD_FAVOR_SMALL_CODE are both defined. Cannot favor speed and size at the same time. | ||
98 | #endif /* MHD_FAVOR_FAST_CODE && MHD_FAVOR_SMALL_CODE */ | ||
99 | |||
100 | /* Define MHD_FAVOR_FAST_CODE to force fast code path or | ||
101 | define MHD_FAVOR_SMALL_CODE to choose compact code path */ | ||
102 | #if !defined(MHD_FAVOR_FAST_CODE) && !defined(MHD_FAVOR_SMALL_CODE) | ||
103 | /* Try to detect user preferences */ | ||
104 | /* Defined by GCC and many compatible compilers */ | ||
105 | #ifdef __OPTIMIZE_SIZE__ | ||
106 | #define MHD_FAVOR_SMALL_CODE 1 | ||
107 | #elif __OPTIMIZE__ | ||
108 | #define MHD_FAVOR_FAST_CODE 1 | ||
109 | #endif /* __OPTIMIZE__ */ | ||
110 | #endif /* !MHD_FAVOR_FAST_CODE && !MHD_FAVOR_SMALL_CODE */ | ||
111 | |||
112 | #if !defined(MHD_FAVOR_FAST_CODE) && !defined(MHD_FAVOR_SMALL_CODE) | ||
113 | /* Use faster code by default */ | ||
114 | #define MHD_FAVOR_FAST_CODE 1 | ||
115 | #endif /* !MHD_FAVOR_FAST_CODE && !MHD_FAVOR_SMALL_CODE */ | ||
116 | |||
96 | #endif /* MHD_OPTIONS_H */ | 117 | #endif /* MHD_OPTIONS_H */ |
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 */ | ||
diff --git a/src/microhttpd/mhd_str.h b/src/microhttpd/mhd_str.h index c0649a2f..880970ca 100644 --- a/src/microhttpd/mhd_str.h +++ b/src/microhttpd/mhd_str.h | |||
@@ -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 |
@@ -26,14 +26,21 @@ | |||
26 | #ifndef MHD_STR_H | 26 | #ifndef MHD_STR_H |
27 | #define MHD_STR_H 1 | 27 | #define MHD_STR_H 1 |
28 | 28 | ||
29 | #include "mhd_options.h" | ||
30 | |||
29 | #include <stdint.h> | 31 | #include <stdint.h> |
30 | #include <stdlib.h> | 32 | #include <stdlib.h> |
31 | 33 | ||
34 | #ifdef MHD_FAVOR_SMALL_CODE | ||
35 | #include "mhd_limits.h" | ||
36 | #endif /* MHD_FAVOR_SMALL_CODE */ | ||
37 | |||
32 | /* | 38 | /* |
33 | * Block of functions/macros that use US-ASCII charset as required by HTTP | 39 | * Block of functions/macros that use US-ASCII charset as required by HTTP |
34 | * standards. Not affected by current locale settings. | 40 | * standards. Not affected by current locale settings. |
35 | */ | 41 | */ |
36 | 42 | ||
43 | #ifndef MHD_FAVOR_SMALL_CODE | ||
37 | /** | 44 | /** |
38 | * Check two string for equality, ignoring case of US-ASCII letters. | 45 | * Check two string for equality, ignoring case of US-ASCII letters. |
39 | * @param str1 first string to compare | 46 | * @param str1 first string to compare |
@@ -43,6 +50,10 @@ | |||
43 | int | 50 | int |
44 | MHD_str_equal_caseless_ (const char * str1, | 51 | MHD_str_equal_caseless_ (const char * str1, |
45 | const char * str2); | 52 | const char * str2); |
53 | #else /* MHD_FAVOR_SMALL_CODE */ | ||
54 | /* Reuse MHD_str_equal_caseless_n_() to reduce size */ | ||
55 | #define MHD_str_equal_caseless_(s1,s2) MHD_str_equal_caseless_n_((s1),(s2), SIZE_MAX) | ||
56 | #endif /* MHD_FAVOR_SMALL_CODE */ | ||
46 | 57 | ||
47 | 58 | ||
48 | /** | 59 | /** |
@@ -60,6 +71,9 @@ MHD_str_equal_caseless_n_ (const char * const str1, | |||
60 | const char * const str2, | 71 | const char * const str2, |
61 | size_t maxlen); | 72 | size_t maxlen); |
62 | 73 | ||
74 | #ifndef MHD_FAVOR_SMALL_CODE | ||
75 | /* Use individual function for each case to improve speed */ | ||
76 | |||
63 | /** | 77 | /** |
64 | * Convert decimal US-ASCII digits in string to number in uint64_t. | 78 | * Convert decimal US-ASCII digits in string to number in uint64_t. |
65 | * Conversion stopped at first non-digit character. | 79 | * Conversion stopped at first non-digit character. |
@@ -186,4 +200,57 @@ MHD_strx_to_uint64_n_ (const char * str, | |||
186 | size_t maxlen, | 200 | size_t maxlen, |
187 | uint64_t * out_val); | 201 | uint64_t * out_val); |
188 | 202 | ||
203 | #else /* MHD_FAVOR_SMALL_CODE */ | ||
204 | /* Use one universal function and macros to reduce size */ | ||
205 | |||
206 | /** | ||
207 | * Generic function for converting not more then @a maxlen | ||
208 | * hexadecimal or decimal US-ASCII digits in string to number. | ||
209 | * Conversion stopped at first non-digit character or after @a maxlen | ||
210 | * digits. | ||
211 | * To be used only within macro. | ||
212 | * @param str the string to convert | ||
213 | * @param maxlen the maximum number of characters to process | ||
214 | * @param out_val the pointer to uint64_t to store result of conversion | ||
215 | * @param val_size the size of variable pointed by @a out_val | ||
216 | * @param max_val the maximum decoded number | ||
217 | * @param base the numeric base, 10 or 16 | ||
218 | * @return non-zero number of characters processed on succeed, | ||
219 | * zero if no digit is found, resulting value is larger | ||
220 | * then @ max_val or @a out_val is NULL | ||
221 | */ | ||
222 | size_t | ||
223 | MHD_str_to_uvalue_n_ (const char * str, | ||
224 | size_t maxlen, | ||
225 | void * out_val, | ||
226 | size_t val_size, | ||
227 | uint64_t max_val, | ||
228 | int base); | ||
229 | |||
230 | #define MHD_str_to_uint64_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ | ||
231 | sizeof(uint64_t),UINT64_MAX,10) | ||
232 | |||
233 | #define MHD_str_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ | ||
234 | sizeof(uint64_t),UINT64_MAX,10) | ||
235 | |||
236 | #define MHD_strx_to_sizet_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ | ||
237 | sizeof(size_t),SIZE_MAX,16) | ||
238 | |||
239 | #define MHD_strx_to_sizet_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ | ||
240 | sizeof(size_t),SIZE_MAX,16) | ||
241 | |||
242 | #define MHD_strx_to_uint32_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ | ||
243 | sizeof(uint32_t),UINT32_MAX,16) | ||
244 | |||
245 | #define MHD_strx_to_uint32_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ | ||
246 | sizeof(uint32_t),UINT32_MAX,16) | ||
247 | |||
248 | #define MHD_strx_to_uint64_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ | ||
249 | sizeof(uint64_t),UINT64_MAX,16) | ||
250 | |||
251 | #define MHD_strx_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ | ||
252 | sizeof(uint64_t),UINT64_MAX,16) | ||
253 | |||
254 | #endif /* MHD_FAVOR_SMALL_CODE */ | ||
255 | |||
189 | #endif /* MHD_STR_H */ | 256 | #endif /* MHD_STR_H */ |