http: fix warning when sizeof(off_t) == sizeof(long long)
[unicorn.git] / ext / unicorn_http / c_util.h
blob04fd05d396145fe935d086c8cb8b2cd482a27f18
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
33 * capitalizes all lower-case ASCII characters and converts dashes
34 * to underscores for HTTP headers. Locale-agnostic.
36 static void snake_upcase_char(char *c)
38 if (*c >= 'a' && *c <= 'z')
39 *c &= ~0x20;
40 else if (*c == '-')
41 *c = '_';
44 /* Downcases a single ASCII character. Locale-agnostic. */
45 static void downcase_char(char *c)
47 if (*c >= 'A' && *c <= 'Z')
48 *c |= 0x20;
51 static int hexchar2int(int xdigit)
53 if (xdigit >= 'A' && xdigit <= 'F')
54 return xdigit - 'A' + 10;
55 if (xdigit >= 'a' && xdigit <= 'f')
56 return xdigit - 'a' + 10;
58 /* Ragel already does runtime range checking for us in Unicorn: */
59 assert(xdigit >= '0' && xdigit <= '9');
61 return xdigit - '0';
65 * multiplies +i+ by +base+ and increments the result by the parsed
66 * integer value of +xdigit+. +xdigit+ is a character byte
67 * representing a number the range of 0..(base-1)
68 * returns the new value of +i+ on success
69 * returns -1 on errors (including overflow)
71 static off_t step_incr(off_t i, int xdigit, const int base)
73 static const off_t max = UH_OFF_T_MAX;
74 const off_t next_max = (max - (max % base)) / base;
75 off_t offset = hexchar2int(xdigit);
77 if (offset > (base - 1))
78 return -1;
79 if (i > next_max)
80 return -1;
81 i *= base;
83 if ((offset > (base - 1)) || ((max - i) < offset))
84 return -1;
86 return i + offset;
90 * parses a non-negative length according to base-10 and
91 * returns it as an off_t value. Returns -1 on errors
92 * (including overflow).
94 static off_t parse_length(const char *value, size_t length)
96 off_t rv;
98 for (rv = 0; length-- && rv >= 0; ++value)
99 rv = step_incr(rv, *value, 10);
101 return rv;
104 #define CONST_MEM_EQ(const_p, buf, len) \
105 ((sizeof(const_p) - 1) == len && !memcmp(const_p, buf, sizeof(const_p) - 1))
107 #endif /* UH_util_h */