Main Page | Modules | Data Structures | Directories | File List | Data Fields

uri.c

00001 /* 
00002  * Copyright (c) 2005-2007 by KoanLogic s.r.l. - All rights reserved.  
00003  */
00004 
00005 static const char rcsid[] =
00006     "$Id: uri.c,v 1.2 2007/02/12 08:32:27 tho Exp $";
00007 
00008 #include <stdlib.h>
00009 #include <string.h>
00010 
00011 #include <toolbox/uri.h>
00012 #include <toolbox/carpal.h>
00013 #include <toolbox/misc.h>
00014 #include <toolbox/memory.h>
00015 
00021 /* split a string separated by 'c' in two substrings */
00022 static int split(const char *s, size_t len, char c, char **left, char **right)
00023 {
00024     char *buf = 0;
00025     const char *p;
00026     char *l = 0, *r = 0;
00027     
00028     buf = u_strndup(s, len);
00029     nop_err_if(!buf);
00030 
00031     if((p = strchr(buf, c)) != NULL)
00032     {
00033         l = u_strndup(s, p - buf);
00034         r = u_strndup(1 + p, len - (p - buf) - 1);
00035         nop_err_if(!l || !r);
00036     } else {
00037         r = NULL;
00038         nop_err_if((l = u_strndup(buf, len)) == NULL);
00039     }
00040 
00041     /* return result strings */
00042     *left = l;
00043     *right = r;
00044 
00045     U_FREE(buf);
00046 
00047     return 0;
00048 err:
00049     U_FREE(buf);
00050     U_FREE(l);
00051     U_FREE(r);
00052     return ~0;
00053 }
00054 
00055 static int parse_userinfo(const char *s, size_t len, u_uri_t *uri)
00056 {
00057     return split(s, len, ':', &uri->user, &uri->pwd);
00058 }
00059 
00060 static int parse_hostinfo(const char *s, size_t len, u_uri_t *uri)
00061 {
00062     char *port = 0;
00063 
00064     if(split(s, len, ':', &uri->host, &port))
00065         return ~0;
00066 
00067     if(port)
00068     {
00069         uri->port = atoi(port);
00070         U_FREE(port);
00071     }
00072     return 0;
00073 }
00074 
00075 static int parse_middle(const char *s, size_t len, u_uri_t *uri)
00076 {
00077     const char *p;
00078 
00079     if( (p = strchr(s, '@')) == NULL)
00080         return parse_hostinfo(s, len, uri);
00081     else
00082         return parse_userinfo(s, p-s,uri) + parse_hostinfo(1+p, s+len-p-1, uri);
00083 }
00084 
00086 void u_uri_free (u_uri_t *uri)
00087 {
00088     if (uri == NULL)
00089         return;
00090 
00091     U_FREE(uri->scheme);
00092     U_FREE(uri->user);
00093     U_FREE(uri->pwd);
00094     U_FREE(uri->host);
00095     U_FREE(uri->path);
00096     U_FREE(uri);
00097 }
00098 
00100 int u_uri_parse (const char *s, u_uri_t **pu)
00101 {
00102     const char *p, *p0;
00103     int i;
00104     u_uri_t *uri;
00105 
00106     dbg_return_if ((uri = (u_uri_t*) u_zalloc(sizeof(u_uri_t))) == NULL, ~0);
00107 
00108     dbg_err_if ((p = strchr(s, ':')) == NULL); /* err if malformed */
00109 
00110     /* save schema string */
00111     dbg_err_if ((uri->scheme = u_strndup(s, p - s)) == NULL);
00112 
00113     p++; /* skip ':' */
00114 
00115     /* skip "//" */
00116     for (i = 0; i < 2; ++i, ++p)
00117         dbg_err_if (!p || *p == 0 || *p != '/'); /* err if malformed */
00118 
00119     /* save p */
00120     p0 = p; 
00121 
00122     /* find the first path char ('/') or the end of the string */
00123     while (*p && *p != '/')
00124         ++p;
00125 
00126     /* parse userinfo and hostinfo */
00127     dbg_err_if (p - p0 && parse_middle(p0, p - p0, uri));
00128 
00129     /* save path */
00130     dbg_err_if (*p && (uri->path = u_strdup(p)) == NULL);
00131 
00132     *pu = uri;
00133 
00134     return 0;
00135 err:
00136     u_uri_free(uri);
00137     return ~0;
00138 }
00139 

←Products
© 2005-2007 - KoanLogic S.r.l. - All rights reserved