Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
comparison src/encoding/url.c @ 0:d39e1d0d75b6
initial add
author | paulo@hit-nxdomain.opendns.com |
---|---|
date | Sat, 20 Feb 2010 21:18:28 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bd792bde9ee6 |
---|---|
1 /* | |
2 * $Id: url.c,v 1.1 2004/03/24 06:34:36 hipnod Exp $ | |
3 * | |
4 * Copyright (C) 2001-2003 giFT project (gift.sourceforge.net) | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License as published by the | |
8 * Free Software Foundation; either version 2, or (at your option) any | |
9 * later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, but | |
12 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * General Public License for more details. | |
15 */ | |
16 | |
17 #include "gt_gnutella.h" | |
18 #include "encoding/url.h" | |
19 | |
20 #include <ctype.h> | |
21 | |
22 /*****************************************************************************/ | |
23 /* url decode/encode helpers */ | |
24 | |
25 static int oct_value_from_hex (char hex_char) | |
26 { | |
27 if (!isxdigit (hex_char)) | |
28 return 0; | |
29 | |
30 if (hex_char >= '0' && hex_char <= '9') | |
31 return (hex_char - '0'); | |
32 | |
33 hex_char = toupper (hex_char); | |
34 | |
35 return ((hex_char - 'A') + 10); | |
36 } | |
37 | |
38 char *gt_url_decode (const char *encoded) | |
39 { | |
40 char *decoded, *ptr; | |
41 | |
42 if (!encoded) | |
43 return NULL; | |
44 | |
45 /* make sure we are using our own memory here ... */ | |
46 ptr = strdup (encoded); | |
47 | |
48 /* save the head */ | |
49 decoded = ptr; | |
50 | |
51 /* convert '+' -> ' ' and %2x -> char value */ | |
52 while (*ptr) | |
53 { | |
54 switch (*ptr) | |
55 { | |
56 case '+': | |
57 *ptr = ' '; | |
58 break; | |
59 case '%': | |
60 if (isxdigit (ptr[1]) && isxdigit (ptr[2])) | |
61 { | |
62 int oct_val; | |
63 | |
64 oct_val = oct_value_from_hex (ptr[1]) * 16; | |
65 oct_val += oct_value_from_hex (ptr[2]); | |
66 | |
67 *ptr = (char) oct_val; | |
68 | |
69 string_move (ptr + 1, ptr + 3); | |
70 } | |
71 break; | |
72 default: | |
73 break; | |
74 } | |
75 | |
76 ptr++; | |
77 } | |
78 | |
79 return decoded; | |
80 } | |
81 | |
82 static char *gt_url_encode_char (char *stream, unsigned char c) | |
83 { | |
84 const char hex_alpha[] = "0123456789abcdef"; | |
85 | |
86 *stream++ = '%'; | |
87 | |
88 *stream++ = hex_alpha[(c & 0xf0) >> 4]; | |
89 *stream++ = hex_alpha[(c & 0x0f)]; | |
90 | |
91 return stream; | |
92 } | |
93 | |
94 /* | |
95 * This is a bit overzealous about what to encode..hopefully that's ok. This | |
96 * escapes path components ('/'). | |
97 */ | |
98 static BOOL is_safe_char (unsigned char c) | |
99 { | |
100 if (c >= 'A' && c <= 'Z') | |
101 return TRUE; | |
102 | |
103 if (c >= 'a' && c <= 'z') | |
104 return TRUE; | |
105 | |
106 if (c >= '0' && c <= '9') | |
107 return TRUE; | |
108 | |
109 switch (c) | |
110 { | |
111 case '-': | |
112 case '.': | |
113 case '_': | |
114 return TRUE; | |
115 default: | |
116 return FALSE; | |
117 } | |
118 | |
119 return FALSE; | |
120 } | |
121 | |
122 char *gt_url_encode (const char *decoded) | |
123 { | |
124 char *encoded, *ptr; | |
125 unsigned char chr; | |
126 | |
127 if (!decoded) | |
128 return NULL; | |
129 | |
130 /* allocate a large enough buffer for all cases */ | |
131 encoded = ptr = malloc ((strlen (decoded) * 3) + 1); | |
132 | |
133 while ((chr = *decoded) != 0) | |
134 { | |
135 if (is_safe_char (chr)) | |
136 *ptr++ = chr; | |
137 else | |
138 ptr = gt_url_encode_char (ptr, chr); | |
139 | |
140 decoded++; | |
141 } | |
142 | |
143 *ptr = 0; | |
144 | |
145 return encoded; | |
146 } | |
147 | |
148 /*****************************************************************************/ | |
149 | |
150 #if 0 | |
151 int main (int argc, char **argv) | |
152 { | |
153 int i; | |
154 | |
155 for (i = 1; i < argc; i++) | |
156 { | |
157 char *enc, *dec; | |
158 | |
159 enc = gt_url_encode (argv[i]); | |
160 dec = gt_url_decode (enc); | |
161 | |
162 printf ("%s\n%s\n%s\n", argv[i], enc, dec); | |
163 | |
164 assert (strcmp (argv[i], dec) == 0); | |
165 } | |
166 | |
167 return 0; | |
168 } | |
169 #endif |