01 // vim: set ft=cpp:
02 
03 #define URL_EPARSE    (-201)
04 #define URL_EPROTOCOL (-202)
05 
06 class CUrl {
07   U8* protocol;
08   U8* host;
09   U16 port;
10   U8* path;
11 };
12 
13 U0 UrlInit(CUrl* url) {
14   url->protocol = 0;
15   url->host = 0;
16   url->port = 0;
17   url->path = 0;
18 }
19 
20 U0 UrlFree(CUrl* url) {
21   Free(url->protocol);
22   Free(url->host);
23   Free(url->path);
24   UrlInit(url);
25 }
26 
27 Bool UrlParse(U8* url, CUrl* url_out) {
28   U8* colon = StrFirstOcc(url, ":");
29   U8* protosep = StrFind("//", url);
30 
31   if (colon && colon < protosep) {
32     I64 len = colon - url;
33     url_out->protocol = MAlloc(len + 1);
34     MemCpy(url_out->protocol, url, len);
35     url_out->protocol[len] = 0;
36 
37     url = colon + 1;
38     while (*url == '/')
39       url++;
40   }
41   else {
42     url_out->protocol = StrNew("http");
43   }
44 
45   I64 pos = 0;
46 
47   while (url[pos]) {
48     if (url[pos] == ':' || url[pos] == '/') {
49       url_out->host = MAlloc(pos + 1);
50       MemCpy(url_out->host, url, pos);
51       url_out->host[pos] = 0;
52 
53       if (url[pos] == ':') {
54         I64 port = 0;
55         U8* end = 0;
56         port = Str2I64(url + pos + 1, 10, &end);
57 
58         url_out->port = port;
59         url_out->path = StrNew(end);
60       }
61       else {
62         url_out->path = StrNew(url + pos);
63       }
64 
65       return TRUE;
66     }
67 
68     pos++;
69   }
70 
71   url_out->host = StrNew(url);
72   return TRUE;
73 }