From f3730d9037ce7c958b964d84212fe9ac3699cedc Mon Sep 17 00:00:00 2001 From: Rodrigo Moya Date: Mon, 1 Oct 2001 19:25:06 +0000 Subject: added basic URI management functions 2001-10-01 Rodrigo Moya * e-url.[ch]: added basic URI management functions * Makefile.am: added BONOBO flags to make it compile with latest Bonobo, which installs headers in a version-based directory svn path=/trunk/; revision=13274 --- e-util/e-url.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) (limited to 'e-util/e-url.c') diff --git a/e-util/e-url.c b/e-util/e-url.c index 8b54a81d16..ae37c71a74 100644 --- a/e-util/e-url.c +++ b/e-util/e-url.c @@ -6,6 +6,7 @@ * Copyright (C) 2001 Ximian, Inc. * * Developed by Jon Trowbridge + * Rodrigo Moya */ /* @@ -26,6 +27,7 @@ */ #include +#include #include #include "e-url.h" @@ -84,3 +86,178 @@ e_url_equal (const char *url1, const char *url2) return rv; } + +#define HEXVAL(c) (isdigit (c) ? (c) - '0' : tolower (c) - 'a' + 10) + +static void +uri_decode (char *part) +{ + guchar *s, *d; + + s = d = (guchar *)part; + while (*s) { + if (*s == '%') { + if (isxdigit (s[1]) && isxdigit (s[2])) { + *d++ = HEXVAL (s[1]) * 16 + HEXVAL (s[2]); + s += 3; + } else + *d++ = *s++; + } else + *d++ = *s++; + } + *d = '\0'; +} + +EUri * +e_uri_new (const char *uri_string) +{ + EUri *uri; + const char *end, *hash, *colon, *semi, *at, *slash, *question; + const char *p; + + uri = g_new0 (EUri, 1); + + /* find fragment */ + end = hash = strchr (uri_string, '#'); + if (hash && hash[1]) { + uri->fragment = g_strdup (hash + 1); + uri_decode (uri->fragment); + } + else + end = uri_string + strlen (uri_string); + + /* find protocol: initial [a-z+.-]* substring until ":" */ + p = uri_string; + while (p < end && (isalnum ((unsigned char) *p) || + *p == '.' || *p == '+' || *p == '-')) + p++; + + if (p > uri_string && *p == ':') { + uri->protocol = g_strndup (uri_string, p - uri_string); + g_strdown (uri->protocol); + uri_string = p + 1; + } + + if (!*uri_string) + return uri; + + /* check for authority */ + if (strncmp (uri_string, "//", 2) == 0) { + uri_string += 2; + + slash = uri_string + strcspn (uri_string, "/#"); + at = strchr (uri_string, '@'); + if (at && at < slash) { + colon = strchr (uri_string, ':'); + if (colon && colon < at) { + uri->passwd = g_strndup (colon + 1, at - colon - 1); + uri_decode (uri->passwd); + } + else { + uri->passwd = NULL; + colon = at; + } + + semi = strchr (uri_string, ';'); + if (semi && semi < colon && + !strncasecmp (semi, ";auth=", 6)) { + uri->authmech = g_strndup (semi + 6, colon - semi - 6); + uri_decode (uri->authmech); + } + else { + uri->authmech = NULL; + semi = colon; + } + + uri->user = g_strndup (uri_string, semi - uri_string); + uri_decode (uri->user); + uri_string = at + 1; + } + else + uri->user = uri->passwd = uri->authmech = NULL; + + /* find host and port */ + colon = strchr (uri_string, ':'); + if (colon && colon < slash) { + uri->host = g_strndup (uri_string, colon - uri_string); + uri->port = strtoul (colon + 1, NULL, 10); + } + else { + uri->host = g_strndup (uri_string, slash - uri_string); + uri_decode (uri->host); + uri->port = 0; + } + + uri_string = slash; + } + + /* find query */ + question = memchr (uri_string, '?', end - uri_string); + if (question) { + if (question[1]) { + uri->query = g_strndup (question + 1, end - (question + 1)); + uri_decode (uri->query); + } + end = question; + } + + /* find parameters */ + semi = memchr (uri_string, ';', end - uri_string); + if (semi) { + if (semi[1]) { + const char *cur, *p, *eq; + char *name, *value; + + for (cur = semi + 1; cur < end; cur = p + 1) { + p = memchr (cur, ';', end - cur); + if (!p) + p = end; + eq = memchr (cur, '=', p - cur); + if (eq) { + name = g_strndup (cur, eq - cur); + value = g_strndup (eq + 1, p - (eq + 1)); + uri_decode (value); + } else { + name = g_strndup (cur, p - cur); + value = g_strdup (""); + } + uri_decode (name); + g_datalist_set_data_full (&uri->params, name, + value, g_free); + g_free (name); + } + } + end = semi; + } + + if (end != uri_string) { + uri->path = g_strndup (uri_string, end - uri_string); + uri_decode (uri->path); + } + + return uri; +} + +void +e_uri_free (EUri *uri) +{ + if (uri) { + g_free (uri->protocol); + g_free (uri->user); + g_free (uri->authmech); + g_free (uri->passwd); + g_free (uri->host); + g_free (uri->path); + g_datalist_clear (&uri->params); + g_free (uri->query); + g_free (uri->fragment); + + g_free (uri); + } +} + +const char * +e_uri_get_param (EUri *uri, const char *name) +{ + return g_datalist_get_data (&uri->params, name); +} -- cgit v1.2.3