aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-07-23 18:55:09 +0000
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-07-23 18:55:09 +0000
commit43bb6196b0d76d04afca8dd478a47f38352b6e29 (patch)
tree19d5c9f9a016bdb94e96f0503e74a982f56af080
parentabdd48c5f2ca74db2501a4e52245dfc8bd470710 (diff)
downloadlibmicrohttpd-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.
-rw-r--r--src/include/mhd_options.h21
-rw-r--r--src/microhttpd/mhd_str.c103
-rw-r--r--src/microhttpd/mhd_str.h69
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
155todigitvalue (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 */
655size_t
656MHD_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 @@
43int 50int
44MHD_str_equal_caseless_ (const char * str1, 51MHD_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 */
222size_t
223MHD_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 */