Mercurial > audlegacy
annotate Plugins/Input/wma/libffwma/uri.c @ 1715:14e6dd38e108 trunk
[svn] Fixed 3 warnings, 2 unused variables and 1 missing include
author | js |
---|---|
date | Sat, 16 Sep 2006 10:08:23 -0700 |
parents | 850f1eba9cbd |
children |
rev | line source |
---|---|
1410 | 1 /* GNet - Networking library |
2 * Copyright (C) 2000-2003 David Helder, David Bolcsfoldi, Eric Williams | |
3 * | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public | |
15 * License along with this library; if not, write to the | |
1458
f12d7e208b43
[svn] Update FSF address in copyright notices. Update autotools templates.
chainsaw
parents:
1410
diff
changeset
|
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
1459 | 17 * Boston, MA 02110-1301, USA. |
1410 | 18 */ |
19 | |
20 /* FIXME: #include "gnet-private.h" */ | |
21 #include <glib.h> | |
22 #include <string.h> | |
1539
850f1eba9cbd
[svn] - switch to stdlib/unistd.h for malloc (all C89/C99 systems have these). fixes bug #539.
nenolod
parents:
1459
diff
changeset
|
23 #include <stdlib.h> |
850f1eba9cbd
[svn] - switch to stdlib/unistd.h for malloc (all C89/C99 systems have these). fixes bug #539.
nenolod
parents:
1459
diff
changeset
|
24 #include <unistd.h> |
1410 | 25 #include <ctype.h> |
26 | |
27 #include "uri.h" | |
28 #include <string.h> | |
29 | |
30 static void field_unescape (char *str); | |
31 static char* field_escape (char* str, unsigned char mask); | |
32 | |
33 #define USERINFO_ESCAPE_MASK 0x01 | |
34 #define PATH_ESCAPE_MASK 0x02 | |
35 #define QUERY_ESCAPE_MASK 0x04 | |
36 #define FRAGMENT_ESCAPE_MASK 0x08 | |
37 | |
38 /* #define FALSE 0 */ | |
39 /* #define TRUE (!FALSE) */ | |
40 | |
41 static unsigned char neednt_escape_table[] = | |
42 { | |
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
47 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f, | |
48 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, | |
49 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, | |
50 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x0c, | |
51 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, | |
52 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, | |
53 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, | |
54 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f, | |
55 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, | |
56 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, | |
57 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, | |
58 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, | |
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
75 }; | |
76 | |
77 | |
78 /* | |
79 Perl code to generate above table: | |
80 | |
81 #!/usr/bin/perl | |
82 | |
83 $ok = "abcdefghijklmnopqrstuvwxyz" . | |
84 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" . | |
85 "0123456789" . | |
86 "-_.!~*'()"; | |
87 $userinfo_ok = ';:&=+\$,'; | |
88 $path_ok = ':\@&=+\$,;/'; | |
89 $query_ok = ';/?:\@&=+\$,'; | |
90 $fragment_ok = ';/?:\@&=+\$,'; | |
91 | |
92 for ($i = 0; $i < 32; $i++) | |
93 { | |
94 print " "; | |
95 for ($j = 0; $j < 8; $j++) | |
96 { | |
97 $num = 0; | |
98 $letter = chr(($i * 8) + $j); | |
99 | |
100 $num |= 0b0001 if (index($userinfo_ok, $letter) != -1); | |
101 $num |= 0b0010 if (index($path_ok, $letter) != -1); | |
102 $num |= 0b0100 if (index($query_ok, $letter) != -1); | |
103 $num |= 0b1000 if (index($fragment_ok, $letter) != -1); | |
104 $num |= 0b1111 if (index($ok, $letter) != -1); | |
105 | |
106 printf "0x%02x, ", $num; | |
107 } | |
108 print "\n"; | |
109 } | |
110 */ | |
111 | |
112 | |
113 /* our own ISSPACE. ANSI isspace is local dependent */ | |
114 #define ISSPACE(C) (((C) >= 9 && (C) <= 13) || (C) == ' ') | |
115 | |
116 | |
117 static int split_user_passwd(const char* in, char** user, char** passwd) | |
118 { | |
119 char *tmp = strdup(in); | |
120 | |
121 if(!tmp) | |
122 return 0; | |
123 *passwd = strchr(tmp, ':'); | |
124 if(!(*passwd)) | |
125 { | |
126 free(tmp); | |
127 return 0; | |
128 } | |
129 *((*passwd)++) = '\0'; // don't you love C? :) | |
130 | |
131 *user = strdup(tmp); | |
132 if(!*user) | |
133 return 0; | |
134 *passwd = strdup(*passwd); | |
135 if(!*passwd) | |
136 return 0; | |
137 | |
138 free(tmp); | |
139 return 1; | |
140 } | |
141 | |
142 /** | |
143 * gnet_uri_new | |
144 * @uri: URI string | |
145 * | |
146 * Creates a #GURI from a string. Empty fields are set to NULL. The | |
147 * parser does not validate the URI -- it will accept some malformed | |
148 * URI. URIs are usually in the form | |
149 * scheme://userinfo@hostname:port/path?query#fragment | |
150 * | |
151 * URIs created from user input are typically unescaped. URIs | |
152 * created from machine input (e.g. received over the internet) are | |
153 * typically escaped. | |
154 * | |
155 * Returns: a new #GURI, or NULL if there was a failure. | |
156 * | |
157 **/ | |
158 GURI* | |
159 gnet_uri_new (const char* uri) | |
160 { | |
161 GURI* guri = NULL; | |
162 const char* p; | |
163 const char* temp; | |
164 | |
165 g_return_val_if_fail (uri, NULL); | |
166 | |
167 /* Skip initial whitespace */ | |
168 p = uri; | |
169 while (*p && ISSPACE((int)*p)) | |
170 ++p; | |
171 if (!*p) /* Error if it's just a string of space */ | |
172 return NULL; | |
173 | |
174 guri = g_new0 (GURI, 1); | |
175 | |
176 /* Scheme */ | |
177 temp = p; | |
178 while (*p && *p != ':' && *p != '/' && *p != '?' && *p != '#') | |
179 ++p; | |
180 if (*p == ':') | |
181 { | |
182 guri->scheme = g_strndup (temp, p - temp); | |
183 ++p; | |
184 } | |
185 else /* This char is NUL, /, ?, or # */ | |
186 p = temp; | |
187 | |
188 /* Authority */ | |
189 if (*p == '/' && p[1] == '/') | |
190 { | |
191 char *userinfo; | |
192 p += 2; | |
193 | |
194 /* Userinfo */ | |
195 temp = p; | |
196 while (*p && *p != '@' && *p != '/' ) /* Look for @ or / */ | |
197 ++p; | |
198 if (*p == '@') /* Found userinfo */ | |
199 { | |
200 userinfo = g_strndup (temp, p - temp); | |
201 if(!split_user_passwd(userinfo, &guri->user, &guri->passwd)) | |
202 { | |
203 free(userinfo); | |
204 goto error; | |
205 } | |
206 free(userinfo); | |
207 ++p; | |
208 } | |
209 else | |
210 p = temp; | |
211 | |
212 /* Hostname */ | |
213 | |
214 /* Check for IPv6 canonical hostname in brackets */ | |
215 if (*p == '[') | |
216 { | |
217 p++; /* Skip [ */ | |
218 temp = p; | |
219 while (*p && *p != ']') ++p; | |
220 if ((p - temp) == 0) | |
221 goto error; | |
222 guri->hostname = g_strndup (temp, p - temp); | |
223 if (*p) | |
224 p++; /* Skip ] (if there) */ | |
225 } | |
226 else | |
227 { | |
228 temp = p; | |
229 while (*p && *p != '/' && *p != '?' && *p != '#' && *p != ':') ++p; | |
230 if ((p - temp) == 0) | |
231 goto error; | |
232 guri->hostname = g_strndup (temp, p - temp); | |
233 } | |
234 | |
235 /* Port */ | |
236 if (*p == ':') | |
237 { | |
238 for (++p; isdigit((int)*p); ++p) | |
239 guri->port = guri->port * 10 + (*p - '0'); | |
240 } | |
241 | |
242 } | |
243 | |
244 /* Path (we are liberal and won't check if it starts with /) */ | |
245 temp = p; | |
246 while (*p && *p != '?' && *p != '#') | |
247 ++p; | |
248 if (p != temp) | |
249 guri->path = g_strndup(temp, p - temp); | |
250 | |
251 /* Query */ | |
252 if (*p == '?') | |
253 { | |
254 temp = p + 1; | |
255 while (*p && *p != '#') | |
256 ++p; | |
257 guri->query = g_strndup (temp, p - temp); | |
258 } | |
259 | |
260 /* Fragment */ | |
261 if (*p == '#') | |
262 { | |
263 ++p; | |
264 guri->fragment = g_strdup (p); | |
265 } | |
266 | |
267 return guri; | |
268 | |
269 error: | |
270 gnet_uri_delete (guri); | |
271 return NULL; | |
272 } | |
273 | |
274 | |
275 /** | |
276 * gnet_uri_new_fields | |
277 * @scheme: scheme | |
278 * @hostname: host name | |
279 * @port: port | |
280 * @path: path | |
281 * | |
282 * Creates a #GURI from the fields. This function uses the most | |
283 * common fields. Use gnet_uri_new_fields_all() to specify all | |
284 * fields. | |
285 * | |
286 * Returns: a new #GURI. | |
287 * | |
288 **/ | |
289 GURI* | |
290 gnet_uri_new_fields (const char* scheme, const char* hostname, | |
291 const gint port, const char* path) | |
292 { | |
293 GURI* uri = NULL; | |
294 | |
295 uri = g_new0 (GURI, 1); | |
296 if (scheme) uri->scheme = g_strdup (scheme); | |
297 if (hostname) uri->hostname = g_strdup (hostname); | |
298 uri->port = port; | |
299 if (path) uri->path = g_strdup (path); | |
300 | |
301 return uri; | |
302 } | |
303 | |
304 | |
305 /** | |
306 * gnet_uri_new_fields_all | |
307 * @scheme: scheme | |
308 * @userinfo: user info | |
309 * @hostname: host name | |
310 * @port: port | |
311 * @path: path | |
312 * @query: query | |
313 * @fragment: fragment | |
314 * | |
315 * Creates a #GURI from all fields. | |
316 * | |
317 * Returns: a new #GURI. | |
318 * | |
319 **/ | |
320 GURI* | |
321 gnet_uri_new_fields_all (const char* scheme, const char* user, | |
322 const char* passwd, const char* hostname, | |
323 const gint port, const char* path, | |
324 const char* query, const char* fragment) | |
325 { | |
326 GURI* uri = NULL; | |
327 | |
328 uri = g_new0 (GURI, 1); | |
329 if (scheme) uri->scheme = g_strdup (scheme); | |
330 if (user) uri->user = g_strdup (user); | |
331 if (passwd) uri->passwd = g_strdup (passwd); | |
332 if (hostname) uri->hostname = g_strdup (hostname); | |
333 uri->port = port; | |
334 if (path) uri->path = g_strdup (path); | |
335 if (query) uri->query = g_strdup (query); | |
336 if (fragment) uri->fragment = g_strdup (fragment); | |
337 | |
338 return uri; | |
339 } | |
340 | |
341 | |
342 /** | |
343 * gnet_uri_clone: | |
344 * @uri: a #GURI | |
345 * | |
346 * Copies a #GURI. | |
347 * | |
348 * Returns: a copy of @uri. | |
349 * | |
350 **/ | |
351 GURI* | |
352 gnet_uri_clone (const GURI* uri) | |
353 { | |
354 GURI* uri2; | |
355 | |
356 g_return_val_if_fail (uri, NULL); | |
357 | |
358 uri2 = g_new0 (GURI, 1); | |
359 uri2->scheme = g_strdup (uri->scheme); | |
360 uri2->user = g_strdup (uri->user); | |
361 uri2->passwd = g_strdup (uri->passwd); | |
362 uri2->hostname = g_strdup (uri->hostname); | |
363 uri2->port = uri->port; | |
364 uri2->path = g_strdup (uri->path); | |
365 uri2->query = g_strdup (uri->query); | |
366 uri2->fragment = g_strdup (uri->fragment); | |
367 | |
368 return uri2; | |
369 } | |
370 | |
371 | |
372 /** | |
373 * gnet_uri_delete: | |
374 * @uri: a #GURI | |
375 * | |
376 * Deletes a #GURI. | |
377 * | |
378 **/ | |
379 void | |
380 gnet_uri_delete (GURI* uri) | |
381 { | |
382 if (uri) | |
383 { | |
384 g_free (uri->scheme); | |
385 g_free (uri->user); | |
386 g_free (uri->passwd); | |
387 g_free (uri->hostname); | |
388 g_free (uri->path); | |
389 g_free (uri->query); | |
390 g_free (uri->fragment); | |
391 g_free (uri); | |
392 } | |
393 } | |
394 | |
395 | |
396 | |
397 | |
398 #define SAFESTRCMP(A,B) (((A)&&(B))?(strcmp((A),(B))):((A)||(B))) | |
399 | |
400 /** | |
401 * gnet_uri_equal | |
402 * @p1: a #GURI | |
403 * @p2: another #GURI | |
404 * | |
405 * Compares two #GURI's for equality. | |
406 * | |
407 * Returns: TRUE if they are equal; FALSE otherwise. | |
408 * | |
409 **/ | |
410 int | |
411 gnet_uri_equal (gconstpointer p1, gconstpointer p2) | |
412 { | |
413 const GURI* uri1 = (const GURI*) p1; | |
414 const GURI* uri2 = (const GURI*) p2; | |
415 | |
416 g_return_val_if_fail (uri1, FALSE); | |
417 g_return_val_if_fail (uri2, FALSE); | |
418 | |
419 if (uri1->port == uri2->port && | |
420 !SAFESTRCMP(uri1->scheme, uri2->scheme) && | |
421 !SAFESTRCMP(uri1->user, uri2->user) && | |
422 !SAFESTRCMP(uri1->passwd, uri2->passwd) && | |
423 !SAFESTRCMP(uri1->hostname, uri2->hostname) && | |
424 !SAFESTRCMP(uri1->path, uri2->path) && | |
425 !SAFESTRCMP(uri1->query, uri2->query) && | |
426 !SAFESTRCMP(uri1->fragment, uri2->fragment)) | |
427 return TRUE; | |
428 | |
429 return FALSE; | |
430 } | |
431 | |
432 | |
433 /** | |
434 * gnet_uri_hash | |
435 * @p: a #GURI | |
436 * | |
437 * Creates a hash code for @p for use with GHashTable. | |
438 * | |
439 * Returns: hash code for @p. | |
440 * | |
441 **/ | |
442 guint | |
443 gnet_uri_hash (gconstpointer p) | |
444 { | |
445 const GURI* uri = (const GURI*) p; | |
446 guint h = 0; | |
447 | |
448 g_return_val_if_fail (uri, 0); | |
449 | |
450 if (uri->scheme) h = g_str_hash (uri->scheme); | |
451 if (uri->user) h ^= g_str_hash (uri->user); | |
452 if (uri->passwd) h ^= g_str_hash (uri->passwd); | |
453 if (uri->hostname) h ^= g_str_hash (uri->hostname); | |
454 h ^= uri->port; | |
455 if (uri->path) h ^= g_str_hash (uri->path); | |
456 if (uri->query) h ^= g_str_hash (uri->query); | |
457 if (uri->fragment) h ^= g_str_hash (uri->fragment); | |
458 | |
459 return h; | |
460 } | |
461 | |
462 | |
463 /** | |
464 * gnet_uri_escape | |
465 * @uri: a #GURI | |
466 * | |
467 * Escapes the fields in a #GURI. Network protocols use escaped | |
468 * URIs. People use unescaped URIs. | |
469 * | |
470 **/ | |
471 void | |
472 gnet_uri_escape (GURI* uri) | |
473 { | |
474 g_return_if_fail (uri); | |
475 | |
476 uri->user = field_escape (uri->user, USERINFO_ESCAPE_MASK); | |
477 uri->passwd = field_escape (uri->passwd, USERINFO_ESCAPE_MASK); | |
478 uri->path = field_escape (uri->path, PATH_ESCAPE_MASK); | |
479 uri->query = field_escape (uri->query, QUERY_ESCAPE_MASK); | |
480 uri->fragment = field_escape (uri->fragment, FRAGMENT_ESCAPE_MASK); | |
481 } | |
482 | |
483 | |
484 /** | |
485 * gnet_uri_unescape | |
486 * @uri: a #GURI | |
487 * | |
488 * Unescapes the fields in the URI. Network protocols use escaped | |
489 * URIs. People use unescaped URIs. | |
490 * | |
491 **/ | |
492 void | |
493 gnet_uri_unescape (GURI* uri) | |
494 { | |
495 g_return_if_fail (uri); | |
496 | |
497 if (uri->user) | |
498 field_unescape (uri->user); | |
499 if (uri->passwd) | |
500 field_unescape (uri->passwd); | |
501 if (uri->path) | |
502 field_unescape (uri->path); | |
503 if (uri->query) | |
504 field_unescape (uri->query); | |
505 if (uri->fragment) | |
506 field_unescape (uri->fragment); | |
507 } | |
508 | |
509 | |
510 static char* | |
511 field_escape (char* str, unsigned char mask) | |
512 { | |
513 gint len; | |
514 gint i; | |
515 int must_escape = FALSE; | |
516 char* dst; | |
517 gint j; | |
518 | |
519 if (str == NULL) | |
520 return NULL; | |
521 | |
522 /* Roughly calculate buffer size */ | |
523 len = 0; | |
524 for (i = 0; str[i]; i++) | |
525 { | |
526 if (neednt_escape_table[(guint) str[i]] & mask) | |
527 len++; | |
528 else | |
529 { | |
530 len += 3; | |
531 must_escape = TRUE; | |
532 } | |
533 } | |
534 | |
535 /* Don't escape if unnecessary */ | |
536 if (must_escape == FALSE) | |
537 return str; | |
538 | |
539 /* Allocate buffer */ | |
540 dst = (char*) g_malloc(len + 1); | |
541 | |
542 /* Copy */ | |
543 for (i = j = 0; str[i]; i++, j++) | |
544 { | |
545 /* Unescaped character */ | |
546 if (neednt_escape_table[(guint) str[i]] & mask) | |
547 { | |
548 dst[j] = str[i]; | |
549 } | |
550 | |
551 /* Escaped character */ | |
552 else | |
553 { | |
554 dst[j] = '%'; | |
555 | |
556 if (((str[i] & 0xf0) >> 4) < 10) | |
557 dst[j+1] = ((str[i] & 0xf0) >> 4) + '0'; | |
558 else | |
559 dst[j+1] = ((str[i] & 0xf0) >> 4) + 'a' - 10; | |
560 | |
561 if ((str[i] & 0x0f) < 10) | |
562 dst[j+2] = (str[i] & 0x0f) + '0'; | |
563 else | |
564 dst[j+2] = (str[i] & 0x0f) + 'a' - 10; | |
565 | |
566 j += 2; /* and j is incremented in loop too */ | |
567 } | |
568 } | |
569 dst[j] = '\0'; | |
570 | |
571 g_free (str); | |
572 return dst; | |
573 } | |
574 | |
575 | |
576 | |
577 static void | |
578 field_unescape (char* s) | |
579 { | |
580 char* src; | |
581 char* dst; | |
582 | |
583 for (src = dst = s; *src; ++src, ++dst) | |
584 { | |
585 if (src[0] == '%' && src[1] != '\0' && src[2] != '\0') | |
586 { | |
587 gint high, low; | |
588 | |
589 if ('a' <= src[1] && src[1] <= 'f') | |
590 high = src[1] - 'a' + 10; | |
591 else if ('A' <= src[1] && src[1] <= 'F') | |
592 high = src[1] - 'A' + 10; | |
593 else if ('0' <= src[1] && src[1] <= '9') | |
594 high = src[1] - '0'; | |
595 else /* malformed */ | |
596 goto regular_copy; | |
597 | |
598 if ('a' <= src[2] && src[2] <= 'f') | |
599 low = src[2] - 'a' + 10; | |
600 else if ('A' <= src[2] && src[2] <= 'F') | |
601 low = src[2] - 'A' + 10; | |
602 else if ('0' <= src[2] && src[2] <= '9') | |
603 low = src[2] - '0'; | |
604 else /* malformed */ | |
605 goto regular_copy; | |
606 | |
607 *dst = (char)((high << 4) + low); | |
608 src += 2; | |
609 } | |
610 else | |
611 { | |
612 regular_copy: | |
613 *dst = *src; | |
614 } | |
615 } | |
616 | |
617 *dst = '\0'; | |
618 } | |
619 | |
620 | |
621 | |
622 /** | |
623 * gnet_uri_get_string | |
624 * @uri: a #GURI | |
625 * | |
626 * Gets a string representation of a #GURI. This function does not | |
627 * escape or unescape the fields first. Call gnet_uri_escape() or | |
628 * gnet_uri_unescape first if necessary. | |
629 * | |
630 * Returns: a string. | |
631 * | |
632 **/ | |
633 char* | |
634 gnet_uri_get_string (const GURI* uri) | |
635 { | |
636 char* rv = NULL; | |
637 GString* buffer = NULL; | |
638 | |
639 g_return_val_if_fail (uri, NULL); | |
640 | |
641 buffer = g_string_sized_new (16); | |
642 | |
643 if (uri->scheme) | |
644 g_string_sprintfa (buffer, "%s:", uri->scheme); | |
645 | |
646 if (uri->user || uri->passwd || uri->hostname || uri->port) | |
647 g_string_append (buffer, "//"); | |
648 | |
649 if (uri->user) | |
650 { | |
651 buffer = g_string_append (buffer, uri->user); | |
652 buffer = g_string_append_c (buffer, '@'); | |
653 } | |
654 if (uri->passwd) | |
655 { | |
656 buffer = g_string_append (buffer, uri->passwd); | |
657 buffer = g_string_append_c (buffer, '@'); | |
658 } | |
659 | |
660 /* Add brackets around the hostname if it's IPv6 */ | |
661 if (uri->hostname) | |
662 { | |
663 if (strchr(uri->hostname, ':') == NULL) | |
664 buffer = g_string_append (buffer, uri->hostname); | |
665 else | |
666 g_string_sprintfa (buffer, "[%s]", uri->hostname); | |
667 } | |
668 | |
669 if (uri->port) | |
670 g_string_sprintfa (buffer, ":%d", uri->port); | |
671 | |
672 if (uri->path) | |
673 { | |
674 if (*uri->path == '/' || | |
675 !(uri->user || uri->passwd || uri->hostname || uri->port)) | |
676 g_string_append (buffer, uri->path); | |
677 else | |
678 g_string_sprintfa (buffer, "/%s", uri->path); | |
679 } | |
680 | |
681 if (uri->query) | |
682 g_string_sprintfa (buffer, "?%s", uri->query); | |
683 | |
684 if (uri->fragment) | |
685 g_string_sprintfa (buffer, "#%s", uri->fragment); | |
686 | |
687 /* Free only GString not data contained, return the data instead */ | |
688 rv = buffer->str; | |
689 g_string_free (buffer, FALSE); | |
690 return rv; | |
691 } | |
692 | |
693 | |
694 /** | |
695 * gnet_uri_set_scheme | |
696 * @uri: a #GURI | |
697 * @scheme: scheme | |
698 * | |
699 * Sets a #GURI's scheme. | |
700 * | |
701 **/ | |
702 void | |
703 gnet_uri_set_scheme (GURI* uri, const char* scheme) | |
704 { | |
705 g_return_if_fail (uri); | |
706 | |
707 if (uri->scheme) | |
708 { | |
709 g_free (uri->scheme); | |
710 uri->scheme = NULL; | |
711 } | |
712 | |
713 if (scheme) | |
714 uri->scheme = g_strdup (scheme); | |
715 } | |
716 | |
717 | |
718 /** | |
719 * gnet_uri_set_userinfo | |
720 * @uri: a #GURI | |
721 * @userinfo: user info | |
722 * | |
723 * Sets a #GURI's user info. | |
724 * | |
725 **/ | |
726 void | |
727 gnet_uri_set_userinfo (GURI* uri, const char* user, const char* passwd) | |
728 { | |
729 g_return_if_fail (uri); | |
730 | |
731 if (uri->user) | |
732 { | |
733 g_free (uri->user); | |
734 uri->user = NULL; | |
735 } | |
736 if (uri->passwd) | |
737 { | |
738 g_free (uri->passwd); | |
739 uri->passwd = NULL; | |
740 } | |
741 | |
742 if (user) | |
743 uri->user = g_strdup (user); | |
744 if (passwd) | |
745 uri->passwd = g_strdup (passwd); | |
746 } | |
747 | |
748 | |
749 /** | |
750 * gnet_uri_set_hostname | |
751 * @uri: a #GURI | |
752 * @hostname: host name | |
753 * | |
754 * Sets a #GURI's host name. | |
755 * | |
756 **/ | |
757 void | |
758 gnet_uri_set_hostname (GURI* uri, const char* hostname) | |
759 { | |
760 g_return_if_fail (uri); | |
761 | |
762 if (uri->hostname) | |
763 { | |
764 g_free (uri->hostname); | |
765 uri->hostname = NULL; | |
766 } | |
767 | |
768 if (hostname) | |
769 uri->hostname = g_strdup (hostname); | |
770 } | |
771 | |
772 | |
773 /** | |
774 * gnet_uri_set_port | |
775 * @uri: a #GURI | |
776 * @port: port | |
777 * | |
778 * Set a #GURI's port. | |
779 * | |
780 **/ | |
781 void | |
782 gnet_uri_set_port (GURI* uri, gint port) | |
783 { | |
784 uri->port = port; | |
785 } | |
786 | |
787 | |
788 /** | |
789 * gnet_uri_set_path | |
790 * @uri: a #GURI | |
791 * @path: path | |
792 * | |
793 * Set a #GURI's path. | |
794 * | |
795 **/ | |
796 void | |
797 gnet_uri_set_path (GURI* uri, const char* path) | |
798 { | |
799 g_return_if_fail (uri); | |
800 | |
801 if (uri->path) | |
802 { | |
803 g_free (uri->path); | |
804 uri->path = NULL; | |
805 } | |
806 | |
807 if (path) | |
808 uri->path = g_strdup (path); | |
809 } | |
810 | |
811 | |
812 | |
813 /** | |
814 * gnet_uri_set_query | |
815 * @uri: a #GURI | |
816 * @query: query | |
817 * | |
818 * Set a #GURI's query. | |
819 * | |
820 **/ | |
821 void | |
822 gnet_uri_set_query (GURI* uri, const char* query) | |
823 { | |
824 g_return_if_fail (uri); | |
825 | |
826 if (uri->query) | |
827 { | |
828 g_free (uri->query); | |
829 uri->query = NULL; | |
830 } | |
831 | |
832 if (query) | |
833 uri->query = g_strdup (query); | |
834 } | |
835 | |
836 | |
837 /** | |
838 * gnet_uri_set_fragment | |
839 * @uri: a #GURI | |
840 * @fragment: fragment | |
841 * | |
842 * Set a #GURI's fragment. | |
843 * | |
844 **/ | |
845 void | |
846 gnet_uri_set_fragment (GURI* uri, const char* fragment) | |
847 { | |
848 g_return_if_fail (uri); | |
849 | |
850 if (uri->fragment) | |
851 { | |
852 g_free (uri->fragment); | |
853 uri->fragment = NULL; | |
854 } | |
855 | |
856 if (fragment) | |
857 uri->fragment = g_strdup (fragment); | |
858 } |