2 * Generic C functions and macros go here, there are no dependencies
3 * on Unicorn internal structures or the Ruby C API in here.
13 #define MIN(a,b) (a < b ? a : b)
14 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
16 #if SIZEOF_OFF_T == SIZEOF_INT
17 # define UH_OFF_T_MAX INT_MAX
18 #elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
19 # define UH_OFF_T_MAX LLONG_MAX
21 # error off_t size unknown for this platform!
22 #endif /* SIZEOF_OFF_T check */
25 * ragel enforces fpc as a const, and merely casting can make picky
26 * compilers unhappy, so we have this little helper do our dirty work
28 static inline void *deconst(const void *in
)
30 union { const void *in
; void *out
; } tmp
;
38 * capitalizes all lower-case ASCII characters and converts dashes
39 * to underscores for HTTP headers. Locale-agnostic.
41 static void snake_upcase_char(char *c
)
43 if (*c
>= 'a' && *c
<= 'z')
49 /* Downcases a single ASCII character. Locale-agnostic. */
50 static void downcase_char(char *c
)
52 if (*c
>= 'A' && *c
<= 'Z')
56 static int hexchar2int(int xdigit
)
58 if (xdigit
>= 'A' && xdigit
<= 'F')
59 return xdigit
- 'A' + 10;
60 if (xdigit
>= 'a' && xdigit
<= 'f')
61 return xdigit
- 'a' + 10;
63 /* Ragel already does runtime range checking for us in Unicorn: */
64 assert(xdigit
>= '0' && xdigit
<= '9' && "invalid digit character");
70 * multiplies +i+ by +base+ and increments the result by the parsed
71 * integer value of +xdigit+. +xdigit+ is a character byte
72 * representing a number the range of 0..(base-1)
73 * returns the new value of +i+ on success
74 * returns -1 on errors (including overflow)
76 static off_t
step_incr(off_t i
, int xdigit
, const int base
)
78 static const off_t max
= UH_OFF_T_MAX
;
79 const off_t next_max
= (max
- (max
% base
)) / base
;
80 off_t offset
= hexchar2int(xdigit
);
82 if (offset
> (base
- 1))
88 if ((offset
> (base
- 1)) || ((max
- i
) < offset
))
95 * parses a non-negative length according to base-10 and
96 * returns it as an off_t value. Returns -1 on errors
97 * (including overflow).
99 static off_t
parse_length(const char *value
, size_t length
)
103 for (rv
= 0; length
-- && rv
>= 0; ++value
) {
104 if (*value
>= '0' && *value
<= '9')
105 rv
= step_incr(rv
, *value
, 10);
113 #define CONST_MEM_EQ(const_p, buf, len) \
114 ((sizeof(const_p) - 1) == len && !memcmp(const_p, buf, sizeof(const_p) - 1))
116 #endif /* UH_util_h */