1*76404edcSAsim Jamshed #include "buffer.h"
2*76404edcSAsim Jamshed
3*76404edcSAsim Jamshed #include <stdlib.h>
4*76404edcSAsim Jamshed #include <string.h>
5*76404edcSAsim Jamshed
6*76404edcSAsim Jamshed #include <stdio.h>
7*76404edcSAsim Jamshed #include <assert.h>
8*76404edcSAsim Jamshed #include <ctype.h>
9*76404edcSAsim Jamshed
10*76404edcSAsim Jamshed
11*76404edcSAsim Jamshed static const char hex_chars[] = "0123456789abcdef";
12*76404edcSAsim Jamshed
13*76404edcSAsim Jamshed
14*76404edcSAsim Jamshed /**
15*76404edcSAsim Jamshed * init the buffer
16*76404edcSAsim Jamshed *
17*76404edcSAsim Jamshed */
18*76404edcSAsim Jamshed
buffer_init(void)19*76404edcSAsim Jamshed buffer* buffer_init(void) {
20*76404edcSAsim Jamshed buffer *b;
21*76404edcSAsim Jamshed
22*76404edcSAsim Jamshed b = malloc(sizeof(*b));
23*76404edcSAsim Jamshed assert(b);
24*76404edcSAsim Jamshed
25*76404edcSAsim Jamshed b->ptr = NULL;
26*76404edcSAsim Jamshed b->size = 0;
27*76404edcSAsim Jamshed b->used = 0;
28*76404edcSAsim Jamshed
29*76404edcSAsim Jamshed return b;
30*76404edcSAsim Jamshed }
31*76404edcSAsim Jamshed
buffer_init_buffer(buffer * src)32*76404edcSAsim Jamshed buffer *buffer_init_buffer(buffer *src) {
33*76404edcSAsim Jamshed buffer *b = buffer_init();
34*76404edcSAsim Jamshed buffer_copy_string_buffer(b, src);
35*76404edcSAsim Jamshed return b;
36*76404edcSAsim Jamshed }
37*76404edcSAsim Jamshed
38*76404edcSAsim Jamshed /**
39*76404edcSAsim Jamshed * free the buffer
40*76404edcSAsim Jamshed *
41*76404edcSAsim Jamshed */
42*76404edcSAsim Jamshed
buffer_free(buffer * b)43*76404edcSAsim Jamshed void buffer_free(buffer *b) {
44*76404edcSAsim Jamshed if (!b) return;
45*76404edcSAsim Jamshed
46*76404edcSAsim Jamshed free(b->ptr);
47*76404edcSAsim Jamshed free(b);
48*76404edcSAsim Jamshed }
49*76404edcSAsim Jamshed
buffer_reset(buffer * b)50*76404edcSAsim Jamshed void buffer_reset(buffer *b) {
51*76404edcSAsim Jamshed if (!b) return;
52*76404edcSAsim Jamshed
53*76404edcSAsim Jamshed /* limit don't reuse buffer larger than ... bytes */
54*76404edcSAsim Jamshed if (b->size > BUFFER_MAX_REUSE_SIZE) {
55*76404edcSAsim Jamshed free(b->ptr);
56*76404edcSAsim Jamshed b->ptr = NULL;
57*76404edcSAsim Jamshed b->size = 0;
58*76404edcSAsim Jamshed } else if (b->size) {
59*76404edcSAsim Jamshed b->ptr[0] = '\0';
60*76404edcSAsim Jamshed }
61*76404edcSAsim Jamshed
62*76404edcSAsim Jamshed b->used = 0;
63*76404edcSAsim Jamshed }
64*76404edcSAsim Jamshed
65*76404edcSAsim Jamshed
66*76404edcSAsim Jamshed /**
67*76404edcSAsim Jamshed *
68*76404edcSAsim Jamshed * allocate (if neccessary) enough space for 'size' bytes and
69*76404edcSAsim Jamshed * set the 'used' counter to 0
70*76404edcSAsim Jamshed *
71*76404edcSAsim Jamshed */
72*76404edcSAsim Jamshed
73*76404edcSAsim Jamshed #define BUFFER_PIECE_SIZE 64
74*76404edcSAsim Jamshed
buffer_prepare_copy(buffer * b,size_t size)75*76404edcSAsim Jamshed int buffer_prepare_copy(buffer *b, size_t size) {
76*76404edcSAsim Jamshed if (!b) return -1;
77*76404edcSAsim Jamshed
78*76404edcSAsim Jamshed if ((0 == b->size) ||
79*76404edcSAsim Jamshed (size > b->size)) {
80*76404edcSAsim Jamshed if (b->size) free(b->ptr);
81*76404edcSAsim Jamshed
82*76404edcSAsim Jamshed b->size = size;
83*76404edcSAsim Jamshed
84*76404edcSAsim Jamshed /* always allocate a multiply of BUFFER_PIECE_SIZE */
85*76404edcSAsim Jamshed b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
86*76404edcSAsim Jamshed
87*76404edcSAsim Jamshed b->ptr = malloc(b->size);
88*76404edcSAsim Jamshed assert(b->ptr);
89*76404edcSAsim Jamshed }
90*76404edcSAsim Jamshed b->used = 0;
91*76404edcSAsim Jamshed return 0;
92*76404edcSAsim Jamshed }
93*76404edcSAsim Jamshed
94*76404edcSAsim Jamshed /**
95*76404edcSAsim Jamshed *
96*76404edcSAsim Jamshed * increase the internal buffer (if neccessary) to append another 'size' byte
97*76404edcSAsim Jamshed * ->used isn't changed
98*76404edcSAsim Jamshed *
99*76404edcSAsim Jamshed */
100*76404edcSAsim Jamshed
buffer_prepare_append(buffer * b,size_t size)101*76404edcSAsim Jamshed int buffer_prepare_append(buffer *b, size_t size) {
102*76404edcSAsim Jamshed if (!b) return -1;
103*76404edcSAsim Jamshed
104*76404edcSAsim Jamshed if (0 == b->size) {
105*76404edcSAsim Jamshed b->size = size;
106*76404edcSAsim Jamshed
107*76404edcSAsim Jamshed /* always allocate a multiply of BUFFER_PIECE_SIZE */
108*76404edcSAsim Jamshed b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
109*76404edcSAsim Jamshed
110*76404edcSAsim Jamshed b->ptr = malloc(b->size);
111*76404edcSAsim Jamshed b->used = 0;
112*76404edcSAsim Jamshed assert(b->ptr);
113*76404edcSAsim Jamshed } else if (b->used + size > b->size) {
114*76404edcSAsim Jamshed b->size += size;
115*76404edcSAsim Jamshed
116*76404edcSAsim Jamshed /* always allocate a multiply of BUFFER_PIECE_SIZE */
117*76404edcSAsim Jamshed b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
118*76404edcSAsim Jamshed
119*76404edcSAsim Jamshed b->ptr = realloc(b->ptr, b->size);
120*76404edcSAsim Jamshed assert(b->ptr);
121*76404edcSAsim Jamshed }
122*76404edcSAsim Jamshed return 0;
123*76404edcSAsim Jamshed }
124*76404edcSAsim Jamshed
buffer_copy_string(buffer * b,const char * s)125*76404edcSAsim Jamshed int buffer_copy_string(buffer *b, const char *s) {
126*76404edcSAsim Jamshed size_t s_len;
127*76404edcSAsim Jamshed
128*76404edcSAsim Jamshed if (!s || !b) return -1;
129*76404edcSAsim Jamshed
130*76404edcSAsim Jamshed s_len = strlen(s) + 1;
131*76404edcSAsim Jamshed buffer_prepare_copy(b, s_len);
132*76404edcSAsim Jamshed
133*76404edcSAsim Jamshed memcpy(b->ptr, s, s_len);
134*76404edcSAsim Jamshed b->used = s_len;
135*76404edcSAsim Jamshed
136*76404edcSAsim Jamshed return 0;
137*76404edcSAsim Jamshed }
138*76404edcSAsim Jamshed
buffer_copy_string_len(buffer * b,const char * s,size_t s_len)139*76404edcSAsim Jamshed int buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
140*76404edcSAsim Jamshed if (!s || !b) return -1;
141*76404edcSAsim Jamshed #if 0
142*76404edcSAsim Jamshed /* removed optimization as we have to keep the empty string
143*76404edcSAsim Jamshed * in some cases for the config handling
144*76404edcSAsim Jamshed *
145*76404edcSAsim Jamshed * url.access-deny = ( "" )
146*76404edcSAsim Jamshed */
147*76404edcSAsim Jamshed if (s_len == 0) return 0;
148*76404edcSAsim Jamshed #endif
149*76404edcSAsim Jamshed buffer_prepare_copy(b, s_len + 1);
150*76404edcSAsim Jamshed
151*76404edcSAsim Jamshed memcpy(b->ptr, s, s_len);
152*76404edcSAsim Jamshed b->ptr[s_len] = '\0';
153*76404edcSAsim Jamshed b->used = s_len + 1;
154*76404edcSAsim Jamshed
155*76404edcSAsim Jamshed return 0;
156*76404edcSAsim Jamshed }
157*76404edcSAsim Jamshed
buffer_copy_string_buffer(buffer * b,const buffer * src)158*76404edcSAsim Jamshed int buffer_copy_string_buffer(buffer *b, const buffer *src) {
159*76404edcSAsim Jamshed if (!src) return -1;
160*76404edcSAsim Jamshed
161*76404edcSAsim Jamshed if (src->used == 0) {
162*76404edcSAsim Jamshed buffer_reset(b);
163*76404edcSAsim Jamshed return 0;
164*76404edcSAsim Jamshed }
165*76404edcSAsim Jamshed return buffer_copy_string_len(b, src->ptr, src->used - 1);
166*76404edcSAsim Jamshed }
167*76404edcSAsim Jamshed
buffer_append_string(buffer * b,const char * s)168*76404edcSAsim Jamshed int buffer_append_string(buffer *b, const char *s) {
169*76404edcSAsim Jamshed size_t s_len;
170*76404edcSAsim Jamshed
171*76404edcSAsim Jamshed if (!s || !b) return -1;
172*76404edcSAsim Jamshed
173*76404edcSAsim Jamshed s_len = strlen(s);
174*76404edcSAsim Jamshed buffer_prepare_append(b, s_len + 1);
175*76404edcSAsim Jamshed if (b->used == 0)
176*76404edcSAsim Jamshed b->used++;
177*76404edcSAsim Jamshed
178*76404edcSAsim Jamshed memcpy(b->ptr + b->used - 1, s, s_len + 1);
179*76404edcSAsim Jamshed b->used += s_len;
180*76404edcSAsim Jamshed
181*76404edcSAsim Jamshed return 0;
182*76404edcSAsim Jamshed }
183*76404edcSAsim Jamshed
buffer_append_string_rfill(buffer * b,const char * s,size_t maxlen)184*76404edcSAsim Jamshed int buffer_append_string_rfill(buffer *b, const char *s, size_t maxlen) {
185*76404edcSAsim Jamshed size_t s_len;
186*76404edcSAsim Jamshed
187*76404edcSAsim Jamshed if (!s || !b) return -1;
188*76404edcSAsim Jamshed
189*76404edcSAsim Jamshed s_len = strlen(s);
190*76404edcSAsim Jamshed if (s_len > maxlen) s_len = maxlen;
191*76404edcSAsim Jamshed buffer_prepare_append(b, maxlen + 1);
192*76404edcSAsim Jamshed if (b->used == 0)
193*76404edcSAsim Jamshed b->used++;
194*76404edcSAsim Jamshed
195*76404edcSAsim Jamshed memcpy(b->ptr + b->used - 1, s, s_len);
196*76404edcSAsim Jamshed if (maxlen > s_len) {
197*76404edcSAsim Jamshed memset(b->ptr + b->used - 1 + s_len, ' ', maxlen - s_len);
198*76404edcSAsim Jamshed }
199*76404edcSAsim Jamshed
200*76404edcSAsim Jamshed b->used += maxlen;
201*76404edcSAsim Jamshed b->ptr[b->used - 1] = '\0';
202*76404edcSAsim Jamshed return 0;
203*76404edcSAsim Jamshed }
204*76404edcSAsim Jamshed
205*76404edcSAsim Jamshed /**
206*76404edcSAsim Jamshed * append a string to the end of the buffer
207*76404edcSAsim Jamshed *
208*76404edcSAsim Jamshed * the resulting buffer is terminated with a '\0'
209*76404edcSAsim Jamshed * s is treated as a un-terminated string (a \0 is handled a normal character)
210*76404edcSAsim Jamshed *
211*76404edcSAsim Jamshed * @param b a buffer
212*76404edcSAsim Jamshed * @param s the string
213*76404edcSAsim Jamshed * @param s_len size of the string (without the terminating \0)
214*76404edcSAsim Jamshed */
215*76404edcSAsim Jamshed
buffer_append_string_len(buffer * b,const char * s,size_t s_len)216*76404edcSAsim Jamshed int buffer_append_string_len(buffer *b, const char *s, size_t s_len) {
217*76404edcSAsim Jamshed if (!s || !b) return -1;
218*76404edcSAsim Jamshed if (s_len == 0) return 0;
219*76404edcSAsim Jamshed
220*76404edcSAsim Jamshed buffer_prepare_append(b, s_len + 1);
221*76404edcSAsim Jamshed if (b->used == 0)
222*76404edcSAsim Jamshed b->used++;
223*76404edcSAsim Jamshed
224*76404edcSAsim Jamshed memcpy(b->ptr + b->used - 1, s, s_len);
225*76404edcSAsim Jamshed b->used += s_len;
226*76404edcSAsim Jamshed b->ptr[b->used - 1] = '\0';
227*76404edcSAsim Jamshed
228*76404edcSAsim Jamshed return 0;
229*76404edcSAsim Jamshed }
230*76404edcSAsim Jamshed
buffer_append_string_buffer(buffer * b,const buffer * src)231*76404edcSAsim Jamshed int buffer_append_string_buffer(buffer *b, const buffer *src) {
232*76404edcSAsim Jamshed if (!src) return -1;
233*76404edcSAsim Jamshed if (src->used == 0) return 0;
234*76404edcSAsim Jamshed
235*76404edcSAsim Jamshed return buffer_append_string_len(b, src->ptr, src->used - 1);
236*76404edcSAsim Jamshed }
237*76404edcSAsim Jamshed
buffer_append_memory(buffer * b,const char * s,size_t s_len)238*76404edcSAsim Jamshed int buffer_append_memory(buffer *b, const char *s, size_t s_len) {
239*76404edcSAsim Jamshed if (!s || !b) return -1;
240*76404edcSAsim Jamshed if (s_len == 0) return 0;
241*76404edcSAsim Jamshed
242*76404edcSAsim Jamshed buffer_prepare_append(b, s_len);
243*76404edcSAsim Jamshed memcpy(b->ptr + b->used, s, s_len);
244*76404edcSAsim Jamshed b->used += s_len;
245*76404edcSAsim Jamshed
246*76404edcSAsim Jamshed return 0;
247*76404edcSAsim Jamshed }
248*76404edcSAsim Jamshed
buffer_copy_memory(buffer * b,const char * s,size_t s_len)249*76404edcSAsim Jamshed int buffer_copy_memory(buffer *b, const char *s, size_t s_len) {
250*76404edcSAsim Jamshed if (!s || !b) return -1;
251*76404edcSAsim Jamshed
252*76404edcSAsim Jamshed b->used = 0;
253*76404edcSAsim Jamshed
254*76404edcSAsim Jamshed return buffer_append_memory(b, s, s_len);
255*76404edcSAsim Jamshed }
256*76404edcSAsim Jamshed
buffer_append_long_hex(buffer * b,unsigned long value)257*76404edcSAsim Jamshed int buffer_append_long_hex(buffer *b, unsigned long value) {
258*76404edcSAsim Jamshed char *buf;
259*76404edcSAsim Jamshed int shift = 0;
260*76404edcSAsim Jamshed unsigned long copy = value;
261*76404edcSAsim Jamshed
262*76404edcSAsim Jamshed while (copy) {
263*76404edcSAsim Jamshed copy >>= 4;
264*76404edcSAsim Jamshed shift++;
265*76404edcSAsim Jamshed }
266*76404edcSAsim Jamshed if (shift == 0)
267*76404edcSAsim Jamshed shift++;
268*76404edcSAsim Jamshed if (shift & 0x01)
269*76404edcSAsim Jamshed shift++;
270*76404edcSAsim Jamshed
271*76404edcSAsim Jamshed buffer_prepare_append(b, shift + 1);
272*76404edcSAsim Jamshed if (b->used == 0)
273*76404edcSAsim Jamshed b->used++;
274*76404edcSAsim Jamshed buf = b->ptr + (b->used - 1);
275*76404edcSAsim Jamshed b->used += shift;
276*76404edcSAsim Jamshed
277*76404edcSAsim Jamshed shift <<= 2;
278*76404edcSAsim Jamshed while (shift > 0) {
279*76404edcSAsim Jamshed shift -= 4;
280*76404edcSAsim Jamshed *(buf++) = hex_chars[(value >> shift) & 0x0F];
281*76404edcSAsim Jamshed }
282*76404edcSAsim Jamshed *buf = '\0';
283*76404edcSAsim Jamshed
284*76404edcSAsim Jamshed return 0;
285*76404edcSAsim Jamshed }
286*76404edcSAsim Jamshed
LI_ltostr(char * buf,long val)287*76404edcSAsim Jamshed int LI_ltostr(char *buf, long val) {
288*76404edcSAsim Jamshed char swap;
289*76404edcSAsim Jamshed char *end;
290*76404edcSAsim Jamshed int len = 1;
291*76404edcSAsim Jamshed
292*76404edcSAsim Jamshed if (val < 0) {
293*76404edcSAsim Jamshed len++;
294*76404edcSAsim Jamshed *(buf++) = '-';
295*76404edcSAsim Jamshed val = -val;
296*76404edcSAsim Jamshed }
297*76404edcSAsim Jamshed
298*76404edcSAsim Jamshed end = buf;
299*76404edcSAsim Jamshed while (val > 9) {
300*76404edcSAsim Jamshed *(end++) = '0' + (val % 10);
301*76404edcSAsim Jamshed val = val / 10;
302*76404edcSAsim Jamshed }
303*76404edcSAsim Jamshed *(end) = '0' + val;
304*76404edcSAsim Jamshed *(end + 1) = '\0';
305*76404edcSAsim Jamshed len += end - buf;
306*76404edcSAsim Jamshed
307*76404edcSAsim Jamshed while (buf < end) {
308*76404edcSAsim Jamshed swap = *end;
309*76404edcSAsim Jamshed *end = *buf;
310*76404edcSAsim Jamshed *buf = swap;
311*76404edcSAsim Jamshed
312*76404edcSAsim Jamshed buf++;
313*76404edcSAsim Jamshed end--;
314*76404edcSAsim Jamshed }
315*76404edcSAsim Jamshed
316*76404edcSAsim Jamshed return len;
317*76404edcSAsim Jamshed }
318*76404edcSAsim Jamshed
buffer_append_long(buffer * b,long val)319*76404edcSAsim Jamshed int buffer_append_long(buffer *b, long val) {
320*76404edcSAsim Jamshed if (!b) return -1;
321*76404edcSAsim Jamshed
322*76404edcSAsim Jamshed buffer_prepare_append(b, 32);
323*76404edcSAsim Jamshed if (b->used == 0)
324*76404edcSAsim Jamshed b->used++;
325*76404edcSAsim Jamshed
326*76404edcSAsim Jamshed b->used += LI_ltostr(b->ptr + (b->used - 1), val);
327*76404edcSAsim Jamshed return 0;
328*76404edcSAsim Jamshed }
329*76404edcSAsim Jamshed
buffer_copy_long(buffer * b,long val)330*76404edcSAsim Jamshed int buffer_copy_long(buffer *b, long val) {
331*76404edcSAsim Jamshed if (!b) return -1;
332*76404edcSAsim Jamshed
333*76404edcSAsim Jamshed b->used = 0;
334*76404edcSAsim Jamshed return buffer_append_long(b, val);
335*76404edcSAsim Jamshed }
336*76404edcSAsim Jamshed
337*76404edcSAsim Jamshed #if !defined(SIZEOF_LONG) || (SIZEOF_LONG != SIZEOF_OFF_T)
buffer_append_off_t(buffer * b,off_t val)338*76404edcSAsim Jamshed int buffer_append_off_t(buffer *b, off_t val) {
339*76404edcSAsim Jamshed char swap;
340*76404edcSAsim Jamshed char *end;
341*76404edcSAsim Jamshed char *start;
342*76404edcSAsim Jamshed int len = 1;
343*76404edcSAsim Jamshed
344*76404edcSAsim Jamshed if (!b) return -1;
345*76404edcSAsim Jamshed
346*76404edcSAsim Jamshed buffer_prepare_append(b, 32);
347*76404edcSAsim Jamshed if (b->used == 0)
348*76404edcSAsim Jamshed b->used++;
349*76404edcSAsim Jamshed
350*76404edcSAsim Jamshed start = b->ptr + (b->used - 1);
351*76404edcSAsim Jamshed if (val < 0) {
352*76404edcSAsim Jamshed len++;
353*76404edcSAsim Jamshed *(start++) = '-';
354*76404edcSAsim Jamshed val = -val;
355*76404edcSAsim Jamshed }
356*76404edcSAsim Jamshed
357*76404edcSAsim Jamshed end = start;
358*76404edcSAsim Jamshed while (val > 9) {
359*76404edcSAsim Jamshed *(end++) = '0' + (val % 10);
360*76404edcSAsim Jamshed val = val / 10;
361*76404edcSAsim Jamshed }
362*76404edcSAsim Jamshed *(end) = '0' + val;
363*76404edcSAsim Jamshed *(end + 1) = '\0';
364*76404edcSAsim Jamshed len += end - start;
365*76404edcSAsim Jamshed
366*76404edcSAsim Jamshed while (start < end) {
367*76404edcSAsim Jamshed swap = *end;
368*76404edcSAsim Jamshed *end = *start;
369*76404edcSAsim Jamshed *start = swap;
370*76404edcSAsim Jamshed
371*76404edcSAsim Jamshed start++;
372*76404edcSAsim Jamshed end--;
373*76404edcSAsim Jamshed }
374*76404edcSAsim Jamshed
375*76404edcSAsim Jamshed b->used += len;
376*76404edcSAsim Jamshed return 0;
377*76404edcSAsim Jamshed }
378*76404edcSAsim Jamshed
buffer_copy_off_t(buffer * b,off_t val)379*76404edcSAsim Jamshed int buffer_copy_off_t(buffer *b, off_t val) {
380*76404edcSAsim Jamshed if (!b) return -1;
381*76404edcSAsim Jamshed
382*76404edcSAsim Jamshed b->used = 0;
383*76404edcSAsim Jamshed return buffer_append_off_t(b, val);
384*76404edcSAsim Jamshed }
385*76404edcSAsim Jamshed #endif /* !defined(SIZEOF_LONG) || (SIZEOF_LONG != SIZEOF_OFF_T) */
386*76404edcSAsim Jamshed
int2hex(char c)387*76404edcSAsim Jamshed char int2hex(char c) {
388*76404edcSAsim Jamshed return hex_chars[(c & 0x0F)];
389*76404edcSAsim Jamshed }
390*76404edcSAsim Jamshed
391*76404edcSAsim Jamshed /* converts hex char (0-9, A-Z, a-z) to decimal.
392*76404edcSAsim Jamshed * returns 0xFF on invalid input.
393*76404edcSAsim Jamshed */
hex2int(unsigned char hex)394*76404edcSAsim Jamshed char hex2int(unsigned char hex) {
395*76404edcSAsim Jamshed hex = hex - '0';
396*76404edcSAsim Jamshed if (hex > 9) {
397*76404edcSAsim Jamshed hex = (hex + '0' - 1) | 0x20;
398*76404edcSAsim Jamshed hex = hex - 'a' + 11;
399*76404edcSAsim Jamshed }
400*76404edcSAsim Jamshed if (hex > 15)
401*76404edcSAsim Jamshed hex = 0xFF;
402*76404edcSAsim Jamshed
403*76404edcSAsim Jamshed return hex;
404*76404edcSAsim Jamshed }
405*76404edcSAsim Jamshed
406*76404edcSAsim Jamshed
407*76404edcSAsim Jamshed /**
408*76404edcSAsim Jamshed * init the buffer
409*76404edcSAsim Jamshed *
410*76404edcSAsim Jamshed */
411*76404edcSAsim Jamshed
buffer_array_init(void)412*76404edcSAsim Jamshed buffer_array* buffer_array_init(void) {
413*76404edcSAsim Jamshed buffer_array *b;
414*76404edcSAsim Jamshed
415*76404edcSAsim Jamshed b = malloc(sizeof(*b));
416*76404edcSAsim Jamshed
417*76404edcSAsim Jamshed assert(b);
418*76404edcSAsim Jamshed b->ptr = NULL;
419*76404edcSAsim Jamshed b->size = 0;
420*76404edcSAsim Jamshed b->used = 0;
421*76404edcSAsim Jamshed
422*76404edcSAsim Jamshed return b;
423*76404edcSAsim Jamshed }
424*76404edcSAsim Jamshed
buffer_array_reset(buffer_array * b)425*76404edcSAsim Jamshed void buffer_array_reset(buffer_array *b) {
426*76404edcSAsim Jamshed size_t i;
427*76404edcSAsim Jamshed
428*76404edcSAsim Jamshed if (!b) return;
429*76404edcSAsim Jamshed
430*76404edcSAsim Jamshed /* if they are too large, reduce them */
431*76404edcSAsim Jamshed for (i = 0; i < b->used; i++) {
432*76404edcSAsim Jamshed buffer_reset(b->ptr[i]);
433*76404edcSAsim Jamshed }
434*76404edcSAsim Jamshed
435*76404edcSAsim Jamshed b->used = 0;
436*76404edcSAsim Jamshed }
437*76404edcSAsim Jamshed
438*76404edcSAsim Jamshed
439*76404edcSAsim Jamshed /**
440*76404edcSAsim Jamshed * free the buffer_array
441*76404edcSAsim Jamshed *
442*76404edcSAsim Jamshed */
443*76404edcSAsim Jamshed
buffer_array_free(buffer_array * b)444*76404edcSAsim Jamshed void buffer_array_free(buffer_array *b) {
445*76404edcSAsim Jamshed size_t i;
446*76404edcSAsim Jamshed if (!b) return;
447*76404edcSAsim Jamshed
448*76404edcSAsim Jamshed for (i = 0; i < b->size; i++) {
449*76404edcSAsim Jamshed if (b->ptr[i]) buffer_free(b->ptr[i]);
450*76404edcSAsim Jamshed }
451*76404edcSAsim Jamshed free(b->ptr);
452*76404edcSAsim Jamshed free(b);
453*76404edcSAsim Jamshed }
454*76404edcSAsim Jamshed
buffer_array_append_get_buffer(buffer_array * b)455*76404edcSAsim Jamshed buffer *buffer_array_append_get_buffer(buffer_array *b) {
456*76404edcSAsim Jamshed size_t i;
457*76404edcSAsim Jamshed
458*76404edcSAsim Jamshed if (b->size == 0) {
459*76404edcSAsim Jamshed b->size = 16;
460*76404edcSAsim Jamshed b->ptr = malloc(sizeof(*b->ptr) * b->size);
461*76404edcSAsim Jamshed assert(b->ptr);
462*76404edcSAsim Jamshed for (i = 0; i < b->size; i++) {
463*76404edcSAsim Jamshed b->ptr[i] = NULL;
464*76404edcSAsim Jamshed }
465*76404edcSAsim Jamshed } else if (b->size == b->used) {
466*76404edcSAsim Jamshed b->size += 16;
467*76404edcSAsim Jamshed b->ptr = realloc(b->ptr, sizeof(*b->ptr) * b->size);
468*76404edcSAsim Jamshed assert(b->ptr);
469*76404edcSAsim Jamshed for (i = b->used; i < b->size; i++) {
470*76404edcSAsim Jamshed b->ptr[i] = NULL;
471*76404edcSAsim Jamshed }
472*76404edcSAsim Jamshed }
473*76404edcSAsim Jamshed
474*76404edcSAsim Jamshed if (b->ptr[b->used] == NULL) {
475*76404edcSAsim Jamshed b->ptr[b->used] = buffer_init();
476*76404edcSAsim Jamshed }
477*76404edcSAsim Jamshed
478*76404edcSAsim Jamshed b->ptr[b->used]->used = 0;
479*76404edcSAsim Jamshed
480*76404edcSAsim Jamshed return b->ptr[b->used++];
481*76404edcSAsim Jamshed }
482*76404edcSAsim Jamshed
483*76404edcSAsim Jamshed
buffer_search_string_len(buffer * b,const char * needle,size_t len)484*76404edcSAsim Jamshed char * buffer_search_string_len(buffer *b, const char *needle, size_t len) {
485*76404edcSAsim Jamshed size_t i;
486*76404edcSAsim Jamshed if (len == 0) return NULL;
487*76404edcSAsim Jamshed if (needle == NULL) return NULL;
488*76404edcSAsim Jamshed
489*76404edcSAsim Jamshed if (b->used < len) return NULL;
490*76404edcSAsim Jamshed
491*76404edcSAsim Jamshed for(i = 0; i < b->used - len; i++) {
492*76404edcSAsim Jamshed if (0 == memcmp(b->ptr + i, needle, len)) {
493*76404edcSAsim Jamshed return b->ptr + i;
494*76404edcSAsim Jamshed }
495*76404edcSAsim Jamshed }
496*76404edcSAsim Jamshed
497*76404edcSAsim Jamshed return NULL;
498*76404edcSAsim Jamshed }
499*76404edcSAsim Jamshed
buffer_init_string(const char * str)500*76404edcSAsim Jamshed buffer *buffer_init_string(const char *str) {
501*76404edcSAsim Jamshed buffer *b = buffer_init();
502*76404edcSAsim Jamshed
503*76404edcSAsim Jamshed buffer_copy_string(b, str);
504*76404edcSAsim Jamshed
505*76404edcSAsim Jamshed return b;
506*76404edcSAsim Jamshed }
507*76404edcSAsim Jamshed
buffer_is_empty(buffer * b)508*76404edcSAsim Jamshed int buffer_is_empty(buffer *b) {
509*76404edcSAsim Jamshed if (!b) return 1;
510*76404edcSAsim Jamshed return (b->used == 0);
511*76404edcSAsim Jamshed }
512*76404edcSAsim Jamshed
513*76404edcSAsim Jamshed /**
514*76404edcSAsim Jamshed * check if two buffer contain the same data
515*76404edcSAsim Jamshed *
516*76404edcSAsim Jamshed * HISTORY: this function was pretty much optimized, but didn't handled
517*76404edcSAsim Jamshed * alignment properly.
518*76404edcSAsim Jamshed */
519*76404edcSAsim Jamshed
buffer_is_equal(buffer * a,buffer * b)520*76404edcSAsim Jamshed int buffer_is_equal(buffer *a, buffer *b) {
521*76404edcSAsim Jamshed if (a->used != b->used) return 0;
522*76404edcSAsim Jamshed if (a->used == 0) return 1;
523*76404edcSAsim Jamshed
524*76404edcSAsim Jamshed return (0 == strcmp(a->ptr, b->ptr));
525*76404edcSAsim Jamshed }
526*76404edcSAsim Jamshed
buffer_is_equal_string(buffer * a,const char * s,size_t b_len)527*76404edcSAsim Jamshed int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
528*76404edcSAsim Jamshed buffer b;
529*76404edcSAsim Jamshed
530*76404edcSAsim Jamshed b.ptr = (char *)s;
531*76404edcSAsim Jamshed b.used = b_len + 1;
532*76404edcSAsim Jamshed
533*76404edcSAsim Jamshed return buffer_is_equal(a, &b);
534*76404edcSAsim Jamshed }
535*76404edcSAsim Jamshed
536*76404edcSAsim Jamshed /* simple-assumption:
537*76404edcSAsim Jamshed *
538*76404edcSAsim Jamshed * most parts are equal and doing a case conversion needs time
539*76404edcSAsim Jamshed *
540*76404edcSAsim Jamshed */
buffer_caseless_compare(const char * a,size_t a_len,const char * b,size_t b_len)541*76404edcSAsim Jamshed int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) {
542*76404edcSAsim Jamshed size_t ndx = 0, max_ndx;
543*76404edcSAsim Jamshed size_t *al, *bl;
544*76404edcSAsim Jamshed size_t mask = sizeof(*al) - 1;
545*76404edcSAsim Jamshed
546*76404edcSAsim Jamshed al = (size_t *)a;
547*76404edcSAsim Jamshed bl = (size_t *)b;
548*76404edcSAsim Jamshed
549*76404edcSAsim Jamshed /* is the alignment correct ? */
550*76404edcSAsim Jamshed if ( ((size_t)al & mask) == 0 &&
551*76404edcSAsim Jamshed ((size_t)bl & mask) == 0 ) {
552*76404edcSAsim Jamshed
553*76404edcSAsim Jamshed max_ndx = ((a_len < b_len) ? a_len : b_len) & ~mask;
554*76404edcSAsim Jamshed
555*76404edcSAsim Jamshed for (; ndx < max_ndx; ndx += sizeof(*al)) {
556*76404edcSAsim Jamshed if (*al != *bl) break;
557*76404edcSAsim Jamshed al++; bl++;
558*76404edcSAsim Jamshed
559*76404edcSAsim Jamshed }
560*76404edcSAsim Jamshed
561*76404edcSAsim Jamshed }
562*76404edcSAsim Jamshed
563*76404edcSAsim Jamshed a = (char *)al;
564*76404edcSAsim Jamshed b = (char *)bl;
565*76404edcSAsim Jamshed
566*76404edcSAsim Jamshed max_ndx = ((a_len < b_len) ? a_len : b_len);
567*76404edcSAsim Jamshed
568*76404edcSAsim Jamshed for (; ndx < max_ndx; ndx++) {
569*76404edcSAsim Jamshed int a1 = *a++, b1 = *b++;
570*76404edcSAsim Jamshed
571*76404edcSAsim Jamshed if (a1 != b1) {
572*76404edcSAsim Jamshed /* always lowercase for transitive results */
573*76404edcSAsim Jamshed if (a1 >= 'A' && a1 <= 'Z') a1 |= 32;
574*76404edcSAsim Jamshed if (b1 >= 'A' && b1 <= 'Z') b1 |= 32;
575*76404edcSAsim Jamshed
576*76404edcSAsim Jamshed if ((a1 - b1) != 0) return (a1 - b1);
577*76404edcSAsim Jamshed }
578*76404edcSAsim Jamshed }
579*76404edcSAsim Jamshed
580*76404edcSAsim Jamshed /* all chars are the same, and the length match too
581*76404edcSAsim Jamshed *
582*76404edcSAsim Jamshed * they are the same */
583*76404edcSAsim Jamshed if (a_len == b_len) return 0;
584*76404edcSAsim Jamshed
585*76404edcSAsim Jamshed /* if a is shorter then b, then b is larger */
586*76404edcSAsim Jamshed return (a_len - b_len);
587*76404edcSAsim Jamshed }
588*76404edcSAsim Jamshed
589*76404edcSAsim Jamshed
590*76404edcSAsim Jamshed /**
591*76404edcSAsim Jamshed * check if the rightmost bytes of the string are equal.
592*76404edcSAsim Jamshed *
593*76404edcSAsim Jamshed *
594*76404edcSAsim Jamshed */
595*76404edcSAsim Jamshed
buffer_is_equal_right_len(buffer * b1,buffer * b2,size_t len)596*76404edcSAsim Jamshed int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
597*76404edcSAsim Jamshed /* no, len -> equal */
598*76404edcSAsim Jamshed if (len == 0) return 1;
599*76404edcSAsim Jamshed
600*76404edcSAsim Jamshed /* len > 0, but empty buffers -> not equal */
601*76404edcSAsim Jamshed if (b1->used == 0 || b2->used == 0) return 0;
602*76404edcSAsim Jamshed
603*76404edcSAsim Jamshed /* buffers too small -> not equal */
604*76404edcSAsim Jamshed if (b1->used - 1 < len || b1->used - 1 < len) return 0;
605*76404edcSAsim Jamshed
606*76404edcSAsim Jamshed if (0 == strncmp(b1->ptr + b1->used - 1 - len,
607*76404edcSAsim Jamshed b2->ptr + b2->used - 1 - len, len)) {
608*76404edcSAsim Jamshed return 1;
609*76404edcSAsim Jamshed }
610*76404edcSAsim Jamshed
611*76404edcSAsim Jamshed return 0;
612*76404edcSAsim Jamshed }
613*76404edcSAsim Jamshed
buffer_copy_string_hex(buffer * b,const char * in,size_t in_len)614*76404edcSAsim Jamshed int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
615*76404edcSAsim Jamshed size_t i;
616*76404edcSAsim Jamshed
617*76404edcSAsim Jamshed /* BO protection */
618*76404edcSAsim Jamshed if (in_len * 2 < in_len) return -1;
619*76404edcSAsim Jamshed
620*76404edcSAsim Jamshed buffer_prepare_copy(b, in_len * 2 + 1);
621*76404edcSAsim Jamshed
622*76404edcSAsim Jamshed for (i = 0; i < in_len; i++) {
623*76404edcSAsim Jamshed b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F];
624*76404edcSAsim Jamshed b->ptr[b->used++] = hex_chars[in[i] & 0x0F];
625*76404edcSAsim Jamshed }
626*76404edcSAsim Jamshed b->ptr[b->used++] = '\0';
627*76404edcSAsim Jamshed
628*76404edcSAsim Jamshed return 0;
629*76404edcSAsim Jamshed }
630*76404edcSAsim Jamshed
631*76404edcSAsim Jamshed /* everything except: ! ( ) * - . 0-9 A-Z _ a-z */
632*76404edcSAsim Jamshed static const char encoded_chars_rel_uri_part[] = {
633*76404edcSAsim Jamshed /*
634*76404edcSAsim Jamshed 0 1 2 3 4 5 6 7 8 9 A B C D E F
635*76404edcSAsim Jamshed */
636*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
637*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
638*76404edcSAsim Jamshed 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, /* 20 - 2F space " # $ % & ' + , / */
639*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; < = > ? */
640*76404edcSAsim Jamshed 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F @ */
641*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, /* 50 - 5F [ \ ] ^ */
642*76404edcSAsim Jamshed 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F ` */
643*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /* 70 - 7F { | } ~ DEL */
644*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
645*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
646*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */
647*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B0 - BF */
648*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0 - CF */
649*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D0 - DF */
650*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0 - EF */
651*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
652*76404edcSAsim Jamshed };
653*76404edcSAsim Jamshed
654*76404edcSAsim Jamshed /* everything except: ! ( ) * - . / 0-9 A-Z _ a-z */
655*76404edcSAsim Jamshed static const char encoded_chars_rel_uri[] = {
656*76404edcSAsim Jamshed /*
657*76404edcSAsim Jamshed 0 1 2 3 4 5 6 7 8 9 A B C D E F
658*76404edcSAsim Jamshed */
659*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
660*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
661*76404edcSAsim Jamshed 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, /* 20 - 2F space " # $ % & ' + , */
662*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; < = > ? */
663*76404edcSAsim Jamshed 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F @ */
664*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, /* 50 - 5F [ \ ] ^ */
665*76404edcSAsim Jamshed 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F ` */
666*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /* 70 - 7F { | } ~ DEL */
667*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
668*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
669*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */
670*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B0 - BF */
671*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0 - CF */
672*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D0 - DF */
673*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0 - EF */
674*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
675*76404edcSAsim Jamshed };
676*76404edcSAsim Jamshed
677*76404edcSAsim Jamshed static const char encoded_chars_html[] = {
678*76404edcSAsim Jamshed /*
679*76404edcSAsim Jamshed 0 1 2 3 4 5 6 7 8 9 A B C D E F
680*76404edcSAsim Jamshed */
681*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
682*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
683*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 2F & */
684*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 30 - 3F < > */
685*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */
686*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 - 5F */
687*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */
688*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 70 - 7F DEL */
689*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
690*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
691*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */
692*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B0 - BF */
693*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0 - CF */
694*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D0 - DF */
695*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0 - EF */
696*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
697*76404edcSAsim Jamshed };
698*76404edcSAsim Jamshed
699*76404edcSAsim Jamshed static const char encoded_chars_minimal_xml[] = {
700*76404edcSAsim Jamshed /*
701*76404edcSAsim Jamshed 0 1 2 3 4 5 6 7 8 9 A B C D E F
702*76404edcSAsim Jamshed */
703*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
704*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
705*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 2F & */
706*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 30 - 3F < > */
707*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */
708*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 - 5F */
709*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */
710*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 70 - 7F DEL */
711*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
712*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
713*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
714*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
715*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
716*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
717*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
718*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
719*76404edcSAsim Jamshed };
720*76404edcSAsim Jamshed
721*76404edcSAsim Jamshed static const char encoded_chars_hex[] = {
722*76404edcSAsim Jamshed /*
723*76404edcSAsim Jamshed 0 1 2 3 4 5 6 7 8 9 A B C D E F
724*76404edcSAsim Jamshed */
725*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
726*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
727*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
728*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */
729*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
730*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
731*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
732*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70 - 7F */
733*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
734*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
735*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */
736*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B0 - BF */
737*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0 - CF */
738*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D0 - DF */
739*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0 - EF */
740*76404edcSAsim Jamshed 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
741*76404edcSAsim Jamshed };
742*76404edcSAsim Jamshed
743*76404edcSAsim Jamshed static const char encoded_chars_http_header[] = {
744*76404edcSAsim Jamshed /*
745*76404edcSAsim Jamshed 0 1 2 3 4 5 6 7 8 9 A B C D E F
746*76404edcSAsim Jamshed */
747*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 00 - 0F */
748*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
749*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 2F */
750*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30 - 3F */
751*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */
752*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 - 5F */
753*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */
754*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 - 7F */
755*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
756*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
757*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
758*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
759*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
760*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
761*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
762*76404edcSAsim Jamshed 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
763*76404edcSAsim Jamshed };
764*76404edcSAsim Jamshed
765*76404edcSAsim Jamshed
766*76404edcSAsim Jamshed
buffer_append_string_encoded(buffer * b,const char * s,size_t s_len,buffer_encoding_t encoding)767*76404edcSAsim Jamshed int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding) {
768*76404edcSAsim Jamshed unsigned char *ds, *d;
769*76404edcSAsim Jamshed size_t d_len, ndx;
770*76404edcSAsim Jamshed const char *map = NULL;
771*76404edcSAsim Jamshed
772*76404edcSAsim Jamshed if (!s || !b) return -1;
773*76404edcSAsim Jamshed
774*76404edcSAsim Jamshed if (b->ptr[b->used - 1] != '\0') {
775*76404edcSAsim Jamshed SEGFAULT();
776*76404edcSAsim Jamshed }
777*76404edcSAsim Jamshed
778*76404edcSAsim Jamshed if (s_len == 0) return 0;
779*76404edcSAsim Jamshed
780*76404edcSAsim Jamshed switch(encoding) {
781*76404edcSAsim Jamshed case ENCODING_REL_URI:
782*76404edcSAsim Jamshed map = encoded_chars_rel_uri;
783*76404edcSAsim Jamshed break;
784*76404edcSAsim Jamshed case ENCODING_REL_URI_PART:
785*76404edcSAsim Jamshed map = encoded_chars_rel_uri_part;
786*76404edcSAsim Jamshed break;
787*76404edcSAsim Jamshed case ENCODING_HTML:
788*76404edcSAsim Jamshed map = encoded_chars_html;
789*76404edcSAsim Jamshed break;
790*76404edcSAsim Jamshed case ENCODING_MINIMAL_XML:
791*76404edcSAsim Jamshed map = encoded_chars_minimal_xml;
792*76404edcSAsim Jamshed break;
793*76404edcSAsim Jamshed case ENCODING_HEX:
794*76404edcSAsim Jamshed map = encoded_chars_hex;
795*76404edcSAsim Jamshed break;
796*76404edcSAsim Jamshed case ENCODING_HTTP_HEADER:
797*76404edcSAsim Jamshed map = encoded_chars_http_header;
798*76404edcSAsim Jamshed break;
799*76404edcSAsim Jamshed case ENCODING_UNSET:
800*76404edcSAsim Jamshed break;
801*76404edcSAsim Jamshed }
802*76404edcSAsim Jamshed
803*76404edcSAsim Jamshed assert(map != NULL);
804*76404edcSAsim Jamshed
805*76404edcSAsim Jamshed /* count to-be-encoded-characters */
806*76404edcSAsim Jamshed for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
807*76404edcSAsim Jamshed if (map[*ds]) {
808*76404edcSAsim Jamshed switch(encoding) {
809*76404edcSAsim Jamshed case ENCODING_REL_URI:
810*76404edcSAsim Jamshed case ENCODING_REL_URI_PART:
811*76404edcSAsim Jamshed d_len += 3;
812*76404edcSAsim Jamshed break;
813*76404edcSAsim Jamshed case ENCODING_HTML:
814*76404edcSAsim Jamshed case ENCODING_MINIMAL_XML:
815*76404edcSAsim Jamshed d_len += 6;
816*76404edcSAsim Jamshed break;
817*76404edcSAsim Jamshed case ENCODING_HTTP_HEADER:
818*76404edcSAsim Jamshed case ENCODING_HEX:
819*76404edcSAsim Jamshed d_len += 2;
820*76404edcSAsim Jamshed break;
821*76404edcSAsim Jamshed case ENCODING_UNSET:
822*76404edcSAsim Jamshed break;
823*76404edcSAsim Jamshed }
824*76404edcSAsim Jamshed } else {
825*76404edcSAsim Jamshed d_len ++;
826*76404edcSAsim Jamshed }
827*76404edcSAsim Jamshed }
828*76404edcSAsim Jamshed
829*76404edcSAsim Jamshed buffer_prepare_append(b, d_len);
830*76404edcSAsim Jamshed
831*76404edcSAsim Jamshed for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
832*76404edcSAsim Jamshed if (map[*ds]) {
833*76404edcSAsim Jamshed switch(encoding) {
834*76404edcSAsim Jamshed case ENCODING_REL_URI:
835*76404edcSAsim Jamshed case ENCODING_REL_URI_PART:
836*76404edcSAsim Jamshed d[d_len++] = '%';
837*76404edcSAsim Jamshed d[d_len++] = hex_chars[((*ds) >> 4) & 0x0F];
838*76404edcSAsim Jamshed d[d_len++] = hex_chars[(*ds) & 0x0F];
839*76404edcSAsim Jamshed break;
840*76404edcSAsim Jamshed case ENCODING_HTML:
841*76404edcSAsim Jamshed case ENCODING_MINIMAL_XML:
842*76404edcSAsim Jamshed d[d_len++] = '&';
843*76404edcSAsim Jamshed d[d_len++] = '#';
844*76404edcSAsim Jamshed d[d_len++] = 'x';
845*76404edcSAsim Jamshed d[d_len++] = hex_chars[((*ds) >> 4) & 0x0F];
846*76404edcSAsim Jamshed d[d_len++] = hex_chars[(*ds) & 0x0F];
847*76404edcSAsim Jamshed d[d_len++] = ';';
848*76404edcSAsim Jamshed break;
849*76404edcSAsim Jamshed case ENCODING_HEX:
850*76404edcSAsim Jamshed d[d_len++] = hex_chars[((*ds) >> 4) & 0x0F];
851*76404edcSAsim Jamshed d[d_len++] = hex_chars[(*ds) & 0x0F];
852*76404edcSAsim Jamshed break;
853*76404edcSAsim Jamshed case ENCODING_HTTP_HEADER:
854*76404edcSAsim Jamshed d[d_len++] = *ds;
855*76404edcSAsim Jamshed d[d_len++] = '\t';
856*76404edcSAsim Jamshed break;
857*76404edcSAsim Jamshed case ENCODING_UNSET:
858*76404edcSAsim Jamshed break;
859*76404edcSAsim Jamshed }
860*76404edcSAsim Jamshed } else {
861*76404edcSAsim Jamshed d[d_len++] = *ds;
862*76404edcSAsim Jamshed }
863*76404edcSAsim Jamshed }
864*76404edcSAsim Jamshed
865*76404edcSAsim Jamshed /* terminate buffer and calculate new length */
866*76404edcSAsim Jamshed b->ptr[b->used + d_len - 1] = '\0';
867*76404edcSAsim Jamshed
868*76404edcSAsim Jamshed b->used += d_len;
869*76404edcSAsim Jamshed
870*76404edcSAsim Jamshed return 0;
871*76404edcSAsim Jamshed }
872*76404edcSAsim Jamshed
873*76404edcSAsim Jamshed
874*76404edcSAsim Jamshed /* decodes url-special-chars inplace.
875*76404edcSAsim Jamshed * replaces non-printable characters with '_'
876*76404edcSAsim Jamshed */
877*76404edcSAsim Jamshed
buffer_urldecode_internal(buffer * url,int is_query)878*76404edcSAsim Jamshed static int buffer_urldecode_internal(buffer *url, int is_query) {
879*76404edcSAsim Jamshed unsigned char high, low;
880*76404edcSAsim Jamshed const char *src;
881*76404edcSAsim Jamshed char *dst;
882*76404edcSAsim Jamshed
883*76404edcSAsim Jamshed if (!url || !url->ptr) return -1;
884*76404edcSAsim Jamshed
885*76404edcSAsim Jamshed src = (const char*) url->ptr;
886*76404edcSAsim Jamshed dst = (char*) url->ptr;
887*76404edcSAsim Jamshed
888*76404edcSAsim Jamshed while ((*src) != '\0') {
889*76404edcSAsim Jamshed if (is_query && *src == '+') {
890*76404edcSAsim Jamshed *dst = ' ';
891*76404edcSAsim Jamshed } else if (*src == '%') {
892*76404edcSAsim Jamshed *dst = '%';
893*76404edcSAsim Jamshed
894*76404edcSAsim Jamshed high = hex2int(*(src + 1));
895*76404edcSAsim Jamshed if (high != 0xFF) {
896*76404edcSAsim Jamshed low = hex2int(*(src + 2));
897*76404edcSAsim Jamshed if (low != 0xFF) {
898*76404edcSAsim Jamshed high = (high << 4) | low;
899*76404edcSAsim Jamshed
900*76404edcSAsim Jamshed /* map control-characters out */
901*76404edcSAsim Jamshed if (high < 32 || high == 127) high = '_';
902*76404edcSAsim Jamshed
903*76404edcSAsim Jamshed *dst = high;
904*76404edcSAsim Jamshed src += 2;
905*76404edcSAsim Jamshed }
906*76404edcSAsim Jamshed }
907*76404edcSAsim Jamshed } else {
908*76404edcSAsim Jamshed *dst = *src;
909*76404edcSAsim Jamshed }
910*76404edcSAsim Jamshed
911*76404edcSAsim Jamshed dst++;
912*76404edcSAsim Jamshed src++;
913*76404edcSAsim Jamshed }
914*76404edcSAsim Jamshed
915*76404edcSAsim Jamshed *dst = '\0';
916*76404edcSAsim Jamshed url->used = (dst - url->ptr) + 1;
917*76404edcSAsim Jamshed
918*76404edcSAsim Jamshed return 0;
919*76404edcSAsim Jamshed }
920*76404edcSAsim Jamshed
buffer_urldecode_path(buffer * url)921*76404edcSAsim Jamshed int buffer_urldecode_path(buffer *url) {
922*76404edcSAsim Jamshed return buffer_urldecode_internal(url, 0);
923*76404edcSAsim Jamshed }
924*76404edcSAsim Jamshed
buffer_urldecode_query(buffer * url)925*76404edcSAsim Jamshed int buffer_urldecode_query(buffer *url) {
926*76404edcSAsim Jamshed return buffer_urldecode_internal(url, 1);
927*76404edcSAsim Jamshed }
928*76404edcSAsim Jamshed
929*76404edcSAsim Jamshed /* Remove "/../", "//", "/./" parts from path.
930*76404edcSAsim Jamshed *
931*76404edcSAsim Jamshed * /blah/.. gets /
932*76404edcSAsim Jamshed * /blah/../foo gets /foo
933*76404edcSAsim Jamshed * /abc/./xyz gets /abc/xyz
934*76404edcSAsim Jamshed * /abc//xyz gets /abc/xyz
935*76404edcSAsim Jamshed *
936*76404edcSAsim Jamshed * NOTE: src and dest can point to the same buffer, in which case,
937*76404edcSAsim Jamshed * the operation is performed in-place.
938*76404edcSAsim Jamshed */
939*76404edcSAsim Jamshed
buffer_path_simplify(buffer * dest,buffer * src)940*76404edcSAsim Jamshed int buffer_path_simplify(buffer *dest, buffer *src)
941*76404edcSAsim Jamshed {
942*76404edcSAsim Jamshed int toklen;
943*76404edcSAsim Jamshed char c, pre1;
944*76404edcSAsim Jamshed char *start, *slash, *walk, *out;
945*76404edcSAsim Jamshed unsigned short pre;
946*76404edcSAsim Jamshed
947*76404edcSAsim Jamshed if (src == NULL || src->ptr == NULL || dest == NULL)
948*76404edcSAsim Jamshed return -1;
949*76404edcSAsim Jamshed
950*76404edcSAsim Jamshed if (src == dest)
951*76404edcSAsim Jamshed buffer_prepare_append(dest, 1);
952*76404edcSAsim Jamshed else
953*76404edcSAsim Jamshed buffer_prepare_copy(dest, src->used + 1);
954*76404edcSAsim Jamshed
955*76404edcSAsim Jamshed walk = src->ptr;
956*76404edcSAsim Jamshed start = dest->ptr;
957*76404edcSAsim Jamshed out = dest->ptr;
958*76404edcSAsim Jamshed slash = dest->ptr;
959*76404edcSAsim Jamshed
960*76404edcSAsim Jamshed
961*76404edcSAsim Jamshed #if defined(__WIN32) || defined(__CYGWIN__)
962*76404edcSAsim Jamshed /* cygwin is treating \ and / the same, so we have to that too
963*76404edcSAsim Jamshed */
964*76404edcSAsim Jamshed
965*76404edcSAsim Jamshed for (walk = src->ptr; *walk; walk++) {
966*76404edcSAsim Jamshed if (*walk == '\\') *walk = '/';
967*76404edcSAsim Jamshed }
968*76404edcSAsim Jamshed walk = src->ptr;
969*76404edcSAsim Jamshed #endif
970*76404edcSAsim Jamshed
971*76404edcSAsim Jamshed while (*walk == ' ') {
972*76404edcSAsim Jamshed walk++;
973*76404edcSAsim Jamshed }
974*76404edcSAsim Jamshed
975*76404edcSAsim Jamshed pre1 = *(walk++);
976*76404edcSAsim Jamshed c = *(walk++);
977*76404edcSAsim Jamshed pre = pre1;
978*76404edcSAsim Jamshed if (pre1 != '/') {
979*76404edcSAsim Jamshed pre = ('/' << 8) | pre1;
980*76404edcSAsim Jamshed *(out++) = '/';
981*76404edcSAsim Jamshed }
982*76404edcSAsim Jamshed *(out++) = pre1;
983*76404edcSAsim Jamshed
984*76404edcSAsim Jamshed if (pre1 == '\0') {
985*76404edcSAsim Jamshed dest->used = (out - start) + 1;
986*76404edcSAsim Jamshed return 0;
987*76404edcSAsim Jamshed }
988*76404edcSAsim Jamshed
989*76404edcSAsim Jamshed while (1) {
990*76404edcSAsim Jamshed if (c == '/' || c == '\0') {
991*76404edcSAsim Jamshed toklen = out - slash;
992*76404edcSAsim Jamshed if (toklen == 3 && pre == (('.' << 8) | '.')) {
993*76404edcSAsim Jamshed out = slash;
994*76404edcSAsim Jamshed if (out > start) {
995*76404edcSAsim Jamshed out--;
996*76404edcSAsim Jamshed while (out > start && *out != '/') {
997*76404edcSAsim Jamshed out--;
998*76404edcSAsim Jamshed }
999*76404edcSAsim Jamshed }
1000*76404edcSAsim Jamshed
1001*76404edcSAsim Jamshed if (c == '\0')
1002*76404edcSAsim Jamshed out++;
1003*76404edcSAsim Jamshed } else if (toklen == 1 || pre == (('/' << 8) | '.')) {
1004*76404edcSAsim Jamshed out = slash;
1005*76404edcSAsim Jamshed if (c == '\0')
1006*76404edcSAsim Jamshed out++;
1007*76404edcSAsim Jamshed }
1008*76404edcSAsim Jamshed
1009*76404edcSAsim Jamshed slash = out;
1010*76404edcSAsim Jamshed }
1011*76404edcSAsim Jamshed
1012*76404edcSAsim Jamshed if (c == '\0')
1013*76404edcSAsim Jamshed break;
1014*76404edcSAsim Jamshed
1015*76404edcSAsim Jamshed pre1 = c;
1016*76404edcSAsim Jamshed pre = (pre << 8) | pre1;
1017*76404edcSAsim Jamshed c = *walk;
1018*76404edcSAsim Jamshed *out = pre1;
1019*76404edcSAsim Jamshed
1020*76404edcSAsim Jamshed out++;
1021*76404edcSAsim Jamshed walk++;
1022*76404edcSAsim Jamshed }
1023*76404edcSAsim Jamshed
1024*76404edcSAsim Jamshed *out = '\0';
1025*76404edcSAsim Jamshed dest->used = (out - start) + 1;
1026*76404edcSAsim Jamshed
1027*76404edcSAsim Jamshed return 0;
1028*76404edcSAsim Jamshed }
1029*76404edcSAsim Jamshed
light_isdigit(int c)1030*76404edcSAsim Jamshed int light_isdigit(int c) {
1031*76404edcSAsim Jamshed return (c >= '0' && c <= '9');
1032*76404edcSAsim Jamshed }
1033*76404edcSAsim Jamshed
light_isxdigit(int c)1034*76404edcSAsim Jamshed int light_isxdigit(int c) {
1035*76404edcSAsim Jamshed if (light_isdigit(c)) return 1;
1036*76404edcSAsim Jamshed
1037*76404edcSAsim Jamshed c |= 32;
1038*76404edcSAsim Jamshed return (c >= 'a' && c <= 'f');
1039*76404edcSAsim Jamshed }
1040*76404edcSAsim Jamshed
light_isalpha(int c)1041*76404edcSAsim Jamshed int light_isalpha(int c) {
1042*76404edcSAsim Jamshed c |= 32;
1043*76404edcSAsim Jamshed return (c >= 'a' && c <= 'z');
1044*76404edcSAsim Jamshed }
1045*76404edcSAsim Jamshed
light_isalnum(int c)1046*76404edcSAsim Jamshed int light_isalnum(int c) {
1047*76404edcSAsim Jamshed return light_isdigit(c) || light_isalpha(c);
1048*76404edcSAsim Jamshed }
1049*76404edcSAsim Jamshed
buffer_to_lower(buffer * b)1050*76404edcSAsim Jamshed int buffer_to_lower(buffer *b) {
1051*76404edcSAsim Jamshed char *c;
1052*76404edcSAsim Jamshed
1053*76404edcSAsim Jamshed if (b->used == 0) return 0;
1054*76404edcSAsim Jamshed
1055*76404edcSAsim Jamshed for (c = b->ptr; *c; c++) {
1056*76404edcSAsim Jamshed if (*c >= 'A' && *c <= 'Z') {
1057*76404edcSAsim Jamshed *c |= 32;
1058*76404edcSAsim Jamshed }
1059*76404edcSAsim Jamshed }
1060*76404edcSAsim Jamshed
1061*76404edcSAsim Jamshed return 0;
1062*76404edcSAsim Jamshed }
1063*76404edcSAsim Jamshed
1064*76404edcSAsim Jamshed
buffer_to_upper(buffer * b)1065*76404edcSAsim Jamshed int buffer_to_upper(buffer *b) {
1066*76404edcSAsim Jamshed char *c;
1067*76404edcSAsim Jamshed
1068*76404edcSAsim Jamshed if (b->used == 0) return 0;
1069*76404edcSAsim Jamshed
1070*76404edcSAsim Jamshed for (c = b->ptr; *c; c++) {
1071*76404edcSAsim Jamshed if (*c >= 'a' && *c <= 'z') {
1072*76404edcSAsim Jamshed *c &= ~32;
1073*76404edcSAsim Jamshed }
1074*76404edcSAsim Jamshed }
1075*76404edcSAsim Jamshed
1076*76404edcSAsim Jamshed return 0;
1077*76404edcSAsim Jamshed }
1078