File Coverage

XS.xs
Criterion Covered Total %
statement 66 68 97.0
branch 45 58 77.5
condition n/a
subroutine n/a
pod n/a
total 111 126 88.1


line stmt bran cond sub pod time code
1             #ifdef __cplusplus
2             extern "C" {
3             #endif
4              
5             #define PERL_NO_GET_CONTEXT /* we want efficiency */
6             #include
7             #include
8             #include
9              
10             #ifdef __cplusplus
11             } /* extern "C" */
12             #endif
13              
14             #include "ppport.h"
15              
16             static char hextbl[256] =
17             /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
18             {
19             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */
20             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */
21             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
22             0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 3 0-9 */
23             0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 @,A-Z */
24             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */
25             0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 `,a-z */
26             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */
27             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */
28             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */
29             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */
30             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */
31             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */
32             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
33             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */
34             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */
35             };
36              
37             static
38             void
39 56           url_decode_key(const char *src, int src_len, char *d, int *key_len) {
40 56           int i, dlen=0;
41 2286 100         for (i = 0; i < src_len; i++ ) {
42 2230 50         if ( src[i] == '%' && isxdigit(src[i+1]) && isxdigit(src[i+2]) ) {
    0          
    0          
43 0           d[dlen++] = hextbl[(U8)src[i+1]] * 16 + hextbl[(U8)src[i+2]];
44 0           i += 2;
45             }
46             else {
47 2230           d[dlen++] = src[i];
48             }
49             }
50 56           *key_len = dlen;
51 56           }
52              
53             static SV *
54 52           url_decode_val(pTHX_ const char *src, int start, int end) {
55 52           int dlen = 0, i = 0;
56             char *d;
57             SV * dst;
58              
59             // Values can be quoted
60 52 100         if ( src[start] == '"' && src[end-1] == '"' ) {
    100          
61 3           start++;
62 3           --end;
63             }
64              
65 52           dst = newSV(0);
66 52 50         (void)SvUPGRADE(dst, SVt_PV);
67 52 50         d = SvGROW(dst, (end - start) * 3 + 1);
    50          
68              
69 271 100         for (i = start; i < end; i++ ) {
70 219 100         if ( src[i] == '%' && isxdigit(src[i+1]) && isxdigit(src[i+2]) ) {
    50          
    50          
71 16           d[dlen++] = hextbl[(U8)src[i+1]] * 16 + hextbl[(U8)src[i+2]];
72 16           i += 2;
73             }
74             else {
75 203           d[dlen++] = src[i];
76             }
77             }
78              
79 52           SvCUR_set(dst, dlen);
80 52           *SvEND(dst) = '\0';
81 52           SvPOK_only(dst);
82 52           return dst;
83             }
84              
85              
86             static
87             void
88 56           renewmem(pTHX_ char **d, int *cur, const int req) {
89 56 100         if ( req > *cur ) {
90 2           *cur = req;
91 2           Renew(*d, *cur, char);
92             }
93 56           }
94              
95              
96             MODULE = Cookie::Baker::XS PACKAGE = Cookie::Baker::XS
97              
98             PROTOTYPES: DISABLE
99              
100             SV *
101             crush_cookie(cookie)
102             SV *cookie
103             PREINIT:
104             char *src, *prev, *p, *key;
105 22           int i, prev_s=0, la, key_len, key_size=64;
106             STRLEN src_len;
107             HV *hv;
108             CODE:
109 22           hv = newHV();
110 22 100         if ( SvOK(cookie) ) {
    50          
    50          
111 21           Newx(key, key_size, char);
112 21 50         src = (char *)SvPV(cookie,src_len);
113 21           prev = src;
114 2711 100         for ( i=0; i
115 2690 100         if ( src[i] == ';' ) {
116 96 100         while ( prev[0] == ' ' ) {
117 42           prev++;
118 42           prev_s++;
119             }
120 54           la = i - prev_s;
121 81 100         while ( prev[la-1] == ' ' ) {
122 27           --la;
123             }
124 54           p = memchr(prev, '=', i - prev_s);
125 54 100         if ( p != NULL ) {
126 52           renewmem(aTHX_ &key, &key_size, (p - prev)*3+1);
127 52           url_decode_key(prev, p - prev, key, &key_len);
128 52 100         if ( !hv_exists(hv, key, key_len) ) {
129 49           (void)hv_store(hv, key, key_len,
130             url_decode_val(aTHX_ prev, p - prev + 1, la ), 0);
131             }
132             }
133 54           prev = &src[i+1];
134 54           prev_s = i + 1;
135             }
136             }
137 21 100         if ( i > prev_s ) {
138 20 100         while ( prev[0] == ' ' ) {
139 11           prev++;
140 11           prev_s++;
141             }
142 9           la = i - prev_s;
143 15 100         while ( prev[la-1] == ' ' ) {
144 6           --la;
145             }
146 9           p = memchr(prev, '=', i - prev_s);
147 9 100         if ( p != NULL ) {
148 4           renewmem(aTHX_ &key, &key_size, (p - prev)*3+1);
149 4           url_decode_key(prev, p - prev, key, &key_len);
150 4 100         if ( !hv_exists(hv, key, key_len) ) {
151 3           (void)hv_store(hv, key, key_len,
152             url_decode_val(aTHX_ prev, p - prev + 1, la ), 0);
153             }
154             }
155             }
156 21           Safefree(key);
157             }
158 22           RETVAL = newRV_noinc((SV *)hv);
159             OUTPUT:
160             RETVAL
161