diff options
Diffstat (limited to 'camel/url-util.c')
-rw-r--r-- | camel/url-util.c | 284 |
1 files changed, 232 insertions, 52 deletions
diff --git a/camel/url-util.c b/camel/url-util.c index d1ea09c6c9..45b5c0691d 100644 --- a/camel/url-util.c +++ b/camel/url-util.c @@ -31,20 +31,96 @@ Uniform Ressource Locators Bertrand. */ +/* + XXX TODO: recover the words between #'s or ?'s after the path */ -#include <ctype.h> /* for isalpha */ -#include <stdlib.h> /* for atoi */ - #include "url-util.h" +typedef gboolean find_item_func(GString *url, GString **item, guint *position, gboolean *error); + +typedef struct { + char *item_name; + GString **item_value; + find_item_func *find_func; +} FindStepStruct; + +static gboolean find_protocol(GString *url, GString **item, guint *position, gboolean *error); +static gboolean find_user(GString *url, GString **item, guint *position, gboolean *error); +static gboolean find_passwd(GString *url, GString **item, guint *position, gboolean *error); +static gboolean find_host(GString *url, GString **item, guint *position, gboolean *error); +static gboolean find_port(GString *url, GString **item, guint *position, gboolean *error); +static gboolean find_path(GString *url, GString **item, guint *position, gboolean *error); + + + +/** + * new_g_url: create an Gurl object from a string + * @url_string: The string containing the URL to scan + * + * This routine takes a GString and parses it as an + * URL of the form: + * protocol://user:password@host:port/path + * there is no test on the values. For example, + * "port" can be a string, not only a number ! + * The Gurl structure fields ar filled with + * the scan results. When a member of the + * general URL can not be found, the corresponding + * Gurl member is NULL + * + * Return value: a Gurl structure containng the URL items. + **/ +Gurl *new_g_url(GString* url_string) +{ + Gurl *g_url; + + GString *protocol; + GString *user; + GString *passwd; + GString *host; + GString *port; + GString *path; + + guint position=0; + gboolean error; + gboolean found; + guint i; + + g_url = g_new(Gurl,1); + +#define NB_STEP_URL 6 + { + FindStepStruct step[NB_STEP_URL] = { + { "protocol", &(g_url->protocol), find_protocol}, + { "user", &(g_url->user), find_user}, + { "password", &(g_url->passwd), find_passwd}, + { "host", &(g_url->host), find_host}, + { "port", &(g_url->port), find_port}, + { "path", &(g_url->path), find_path} + }; + + for (i=0; i<NB_STEP_URL; i++) { + found = step[i].find_func(url_string, + step[i].item_value, + &position, + &error); + } + } + + return g_url; +} + + + +/** So, yes, I must admit there would have been more elegant + ways to do this, but it works, and quite well :) */ static gboolean -find_protocol(GString *url, GString **protocol, guint *position, gboolean *error) +find_protocol(GString *url, GString **item, guint *position, gboolean *error) { guint i; @@ -55,7 +131,7 @@ find_protocol(GString *url, GString **protocol, guint *position, gboolean *error str_url = url->str; len_url = url->len; - *protocol = NULL; + *item = NULL; *error = FALSE; i=*position; @@ -71,7 +147,7 @@ find_protocol(GString *url, GString **protocol, guint *position, gboolean *error { str_protocol = g_strndup(str_url, i-3); - *protocol = g_string_new(str_protocol); + *item = g_string_new(str_protocol); *position=i; return TRUE; } @@ -83,7 +159,7 @@ find_protocol(GString *url, GString **protocol, guint *position, gboolean *error static gboolean -find_user(GString *url, GString **user, guint *position, gboolean *error) +find_user(GString *url, GString **item, guint *position, gboolean *error) { guint i; guint at_pos; @@ -95,7 +171,7 @@ find_user(GString *url, GString **user, guint *position, gboolean *error) str_url = url->str; len_url = url->len; - *user = NULL; + *item = NULL; i=*position; @@ -110,21 +186,21 @@ find_user(GString *url, GString **user, guint *position, gboolean *error) while ( (i<at_pos) && (str_url[i] != ':') ) i++; /* now if i has not been incremented at all, there is no user */ - if (i == *position) return FALSE; + if (i == *position) { + (*position)++; + return FALSE; + } str_user = g_strndup(str_url+ *position, i - *position); - *user = g_string_new(str_user); + *item = g_string_new(str_user); if (i<at_pos) *position=i+1; /* there was a ':', skip it */ else *position=i; - return TRUE; - - - + return TRUE; } static gboolean -find_passwd(GString *url, GString **passwd, guint *position, gboolean *error) +find_passwd(GString *url, GString **item, guint *position, gboolean *error) { guint i; @@ -135,7 +211,7 @@ find_passwd(GString *url, GString **passwd, guint *position, gboolean *error) str_url = url->str; len_url = url->len; - *passwd = NULL; + *item = NULL; i=*position; @@ -150,24 +226,132 @@ find_passwd(GString *url, GString **passwd, guint *position, gboolean *error) } str_passwd = g_strndup(str_url+ *position, i - *position); - *passwd = g_string_new(str_passwd); + *item = g_string_new(str_passwd); *position=i+1; /* skip it the '@' */ return TRUE; +} + + + +static gboolean +find_host(GString *url, GString **item, guint *position, gboolean *error) +{ + guint i; + guint slash_pos; + + gchar *str_url; + gint len_url; + gchar *str_host; + + str_url = url->str; + len_url = url->len; + + *item = NULL; + i=*position; + + + /* find a '/' */ + while ((i<len_url) && (str_url[i] != '/')) i++; + + slash_pos = i; + i = *position; + + /* find a ':' */ + while ( (i<slash_pos) && (str_url[i] != ':') ) i++; + + /* at this point if i has not been incremented at all, + there is no host */ + if (i == *position) { + (*position)++; + return FALSE; + } + + str_host = g_strndup(str_url+ *position, i - *position); + *item = g_string_new(str_host); + if (i<slash_pos) *position=i+1; /* there was a ':', skip it */ + else *position=i; + + return TRUE; +} + +static gboolean +find_port(GString *url, GString **item, guint *position, gboolean *error) +{ + guint i; + guint slash_pos; + + gchar *str_url; + gint len_url; + gchar *str_port; + str_url = url->str; + len_url = url->len; + + *item = NULL; + i=*position; + + /* find a '/' */ + while ((i<len_url) && (str_url[i] != '/')) i++; + + slash_pos = i; + i = *position; + + /* find a ':' */ + while ( (i<slash_pos) && (str_url[i] != ':') ) i++; + + /* at this point if i has not been incremented at all, + there is no port */ + if (i == *position) return FALSE; + + str_port = g_strndup(str_url+ *position, i - *position); + *item = g_string_new(str_port); + *position = i; + return TRUE; } +static gboolean +find_path(GString *url, GString **item, guint *position, gboolean *error) +{ + guint i; + + gchar *str_url; + gint len_url; + gchar *str_path; + + str_url = url->str; + len_url = url->len; + + *item = NULL; + i=*position; + + + /* find a '#' */ + while ((i<len_url) && (str_url[i] != '#') && (str_url[i] != '?')) i++; + + /*i has not been incremented at all, there is no path */ + if (i == *position) return FALSE; + + str_path = g_strndup(str_url+ *position, i - *position); + *item = g_string_new(str_path); + *position=i; + + + return TRUE; +} /* to tests this file : - gcc -o test_url_util `glib-config --cflags` -DTEST_URL_UTIL url-util.c `glib-config --libs + gcc -o test_url_util `glib-config --cflags` -DTEST_URL_UTIL url-util.c `glib-config --libs` ./test_url_util URL */ #ifdef TEST_URL_UTIL + + int main (int argc, char **argv) { @@ -176,47 +360,43 @@ main (int argc, char **argv) GString *protocol; GString *user; GString *passwd; + GString *host; + GString *port; + GString *path; guint position=0; gboolean error; gboolean found; guint i; - + guint i_pos; + +#define NB_STEP_TEST 6 + FindStepStruct test_step[NB_STEP_TEST] = { + { "protocol", &protocol, find_protocol}, + { "user", &user, find_user}, + { "password", &passwd, find_passwd}, + { "host", &host, find_host}, + { "port", &port, find_port}, + { "path", &path, find_path} + }; url = g_string_new(argv[1]); printf("URL to test : %s\n\n", url->str); - - /* Try to find the protocol */ - found = find_protocol(url, &protocol, &position, &error); - if (found) { - printf("protocol found : %s\n", protocol->str); - } else printf("protocol not found in URL\n\n"); - printf("posistion of the next item:\n"); - printf("%s\n", url->str); - for(i=0; i<position; i++) printf(" "); - printf("^\n"); + for (i=0; i<NB_STEP_TEST; i++) { + found = test_step[i].find_func(url, + test_step[i].item_value, + &position, + &error); + if (found) { + printf("\t\t\t\t** %s found : %s\n", + test_step[i].item_name, + (*test_step[i].item_value)->str); + } else printf("** %s not found in URL\n", test_step[i].item_name); + printf("next item position:\n"); + printf("%s\n", url->str); + for(i_pos=0; i_pos<position; i_pos++) printf(" "); + printf("^\n"); - /* Try to find the user name */ - found = find_user(url, &user, &position, &error); - if (found) { - printf("name found : %s\n", user->str); - } else printf("user name not found in URL\n"); - printf("posistion of the next item:\n"); - printf("%s\n", url->str); - for(i=0; i<position; i++) printf(" "); - printf("^\n"); - - /* Try to find the password */ - found = find_passwd(url, &passwd, &position, &error); - if (found) { - printf("passwd found : %s\n", passwd->str); - printf("\n"); - } else printf("passwd not found in URL\n"); - printf("posistion of the next item:\n"); - printf("%s\n", url->str); - for(i=0; i<position; i++) printf(" "); - printf("^\n"); - - - return 0; + } + } #endif /* TEST_URL_UTIL */ |