fixnuta buga v remove_last (nesnizovala grow ptr, ktery tak ubiral znaky a nemenil...
[httpfs.git] / urlencode.c
blob6ef0109947a5ebf039b673448184facc46c014a8
1 #include <stdio.h>
2 #include <ctype.h>
3 #include "grow.h"
4 #include "urlencode.h"
8 static inline unsigned char nib2hex(int c)
10 return (c>=10 ? c+'a'-10 : c + '0');
13 static inline unsigned int hex2nib(unsigned char c)
15 if (isdigit(c))
16 return c - '0';
17 if (c >= 'a' && c <= 'f')
18 return c - 'a' + 10;
19 if (c >= 'A' && c <= 'F')
20 return c - 'A' + 10;
21 return 0;
25 void path_encode(struct grow *g, const char *path)
27 unsigned char c;
28 char buf[3];
30 buf[0] = '%';
32 while ((c = *path++)) {
33 if (isalnum(c) || c == '_' || c == '/' || c == '.') {
34 grow_put(g, c);
35 } else {
36 buf[1] = nib2hex(c>>4);
37 buf[2] = nib2hex(c&15);
38 grow_append(g, buf, 3);
43 void path_decode(struct grow *g, const char *path)
45 unsigned char c, d;
47 while ((c = *path++)) {
48 if (c == '%') {
49 d = hex2nib(*path++) << 4;
50 d += hex2nib(*path++);
51 grow_put(g, d);
52 } else if (c == '&' && !strncasecmp(path, "amp;", 4)) {
53 grow_put(g, '&');
54 path += 4;
55 /* } else if (c == '+') { */
56 /* grow_put(g, ' '); */
57 } else {
58 grow_put(g, c);
63 #ifdef EMO
65 struct grow g = GROW_INIT, h = GROW_INIT;
67 int main(int argc, char *argv[])
69 path_encode(&g, argv[1]);
70 path_decode(&h, argv[2]);
71 grow_put(&g, 0);
72 grow_put(&h, 0);
74 printf("'%s' '%s'\n", g.arr, h.arr);
77 #endif
79 #ifdef MAIN
80 struct grow g = GROW_INIT, h = GROW_INIT;
82 int main(int argc, char *argv[])
84 char *p=argv[1], *r=argv[2];
85 char *pfx=argv[3];
86 if (argc < 4) {
87 printf("usage: %s <http_root> <path> <prefix>\n", argv[0]);
88 return 1;
90 while (*p == *r) {
91 p++;
92 r++;
94 while (*r == '/')
95 r++;
97 grow_puts(&g, pfx);
98 if (pfx[strlen(pfx)-1] != '/')
99 grow_put(&g, '/');
100 path_encode(&g, r);
102 printf("%s\n", grow_cstr(&g));
103 return 0;
106 #endif