aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/mhd_str.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/mhd_str.c')
-rw-r--r--src/microhttpd/mhd_str.c103
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
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 */