configurator: validate :reuseport for boolean-ess
[unicorn.git] / ext / unicorn_http / c_util.h
blobab1fc0e3ba16840aff562fdb2c64d0d235f4dc9f
1 /*
2 * Generic C functions and macros go here, there are no dependencies
3 * on Unicorn internal structures or the Ruby C API in here.
4 */
6 #ifndef UH_util_h
7 #define UH_util_h
9 #include <unistd.h>
10 #include <assert.h>
12 #define MIN(a,b) (a < b ? a : b)
13 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
15 #ifndef SIZEOF_OFF_T
16 # define SIZEOF_OFF_T 4
17 # warning SIZEOF_OFF_T not defined, guessing 4. Did you run extconf.rb?
18 #endif
20 #if SIZEOF_OFF_T == 4
21 # define UH_OFF_T_MAX 0x7fffffff
22 #elif SIZEOF_OFF_T == 8
23 # if SIZEOF_LONG == 4
24 # define UH_OFF_T_MAX 0x7fffffffffffffffLL
25 # else
26 # define UH_OFF_T_MAX 0x7fffffffffffffff
27 # endif
28 #else
29 # error off_t size unknown for this platform!
30 #endif /* SIZEOF_OFF_T check */
33 * ragel enforces fpc as a const, and merely casting can make picky
34 * compilers unhappy, so we have this little helper do our dirty work
36 static inline void *deconst(const void *in)
38 union { const void *in; void *out; } tmp;
40 tmp.in = in;
42 return tmp.out;
46 * capitalizes all lower-case ASCII characters and converts dashes
47 * to underscores for HTTP headers. Locale-agnostic.
49 static void snake_upcase_char(char *c)
51 if (*c >= 'a' && *c <= 'z')
52 *c &= ~0x20;
53 else if (*c == '-')
54 *c = '_';
57 /* Downcases a single ASCII character. Locale-agnostic. */
58 static void downcase_char(char *c)
60 if (*c >= 'A' && *c <= 'Z')
61 *c |= 0x20;
64 static int hexchar2int(int xdigit)
66 if (xdigit >= 'A' && xdigit <= 'F')
67 return xdigit - 'A' + 10;
68 if (xdigit >= 'a' && xdigit <= 'f')
69 return xdigit - 'a' + 10;
71 /* Ragel already does runtime range checking for us in Unicorn: */
72 assert(xdigit >= '0' && xdigit <= '9' && "invalid digit character");
74 return xdigit - '0';
78 * multiplies +i+ by +base+ and increments the result by the parsed
79 * integer value of +xdigit+. +xdigit+ is a character byte
80 * representing a number the range of 0..(base-1)
81 * returns the new value of +i+ on success
82 * returns -1 on errors (including overflow)
84 static off_t step_incr(off_t i, int xdigit, const int base)
86 static const off_t max = UH_OFF_T_MAX;
87 const off_t next_max = (max - (max % base)) / base;
88 off_t offset = hexchar2int(xdigit);
90 if (offset > (base - 1))
91 return -1;
92 if (i > next_max)
93 return -1;
94 i *= base;
96 if ((offset > (base - 1)) || ((max - i) < offset))
97 return -1;
99 return i + offset;
103 * parses a non-negative length according to base-10 and
104 * returns it as an off_t value. Returns -1 on errors
105 * (including overflow).
107 static off_t parse_length(const char *value, size_t length)
109 off_t rv;
111 for (rv = 0; length-- && rv >= 0; ++value) {
112 if (*value >= '0' && *value <= '9')
113 rv = step_incr(rv, *value, 10);
114 else
115 return -1;
118 return rv;
121 #define CONST_MEM_EQ(const_p, buf, len) \
122 ((sizeof(const_p) - 1) == len && !memcmp(const_p, buf, sizeof(const_p) - 1))
124 #endif /* UH_util_h */