view 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
line source
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 */
17 #include "gt_gnutella.h"
18 #include "encoding/url.h"
20 #include <ctype.h>
22 /*****************************************************************************/
23 /* url decode/encode helpers */
25 static int oct_value_from_hex (char hex_char)
26 {
27 if (!isxdigit (hex_char))
28 return 0;
30 if (hex_char >= '0' && hex_char <= '9')
31 return (hex_char - '0');
33 hex_char = toupper (hex_char);
35 return ((hex_char - 'A') + 10);
36 }
38 char *gt_url_decode (const char *encoded)
39 {
40 char *decoded, *ptr;
42 if (!encoded)
43 return NULL;
45 /* make sure we are using our own memory here ... */
46 ptr = strdup (encoded);
48 /* save the head */
49 decoded = ptr;
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;
64 oct_val = oct_value_from_hex (ptr[1]) * 16;
65 oct_val += oct_value_from_hex (ptr[2]);
67 *ptr = (char) oct_val;
69 string_move (ptr + 1, ptr + 3);
70 }
71 break;
72 default:
73 break;
74 }
76 ptr++;
77 }
79 return decoded;
80 }
82 static char *gt_url_encode_char (char *stream, unsigned char c)
83 {
84 const char hex_alpha[] = "0123456789abcdef";
86 *stream++ = '%';
88 *stream++ = hex_alpha[(c & 0xf0) >> 4];
89 *stream++ = hex_alpha[(c & 0x0f)];
91 return stream;
92 }
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;
103 if (c >= 'a' && c <= 'z')
104 return TRUE;
106 if (c >= '0' && c <= '9')
107 return TRUE;
109 switch (c)
110 {
111 case '-':
112 case '.':
113 case '_':
114 return TRUE;
115 default:
116 return FALSE;
117 }
119 return FALSE;
120 }
122 char *gt_url_encode (const char *decoded)
123 {
124 char *encoded, *ptr;
125 unsigned char chr;
127 if (!decoded)
128 return NULL;
130 /* allocate a large enough buffer for all cases */
131 encoded = ptr = malloc ((strlen (decoded) * 3) + 1);
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);
140 decoded++;
141 }
143 *ptr = 0;
145 return encoded;
146 }
148 /*****************************************************************************/
150 #if 0
151 int main (int argc, char **argv)
152 {
153 int i;
155 for (i = 1; i < argc; i++)
156 {
157 char *enc, *dec;
159 enc = gt_url_encode (argv[i]);
160 dec = gt_url_decode (enc);
162 printf ("%s\n%s\n%s\n", argv[i], enc, dec);
164 assert (strcmp (argv[i], dec) == 0);
165 }
167 return 0;
168 }
169 #endif