//URL 的编码和解码
//作者: loyalman
//日期: 2003/06/12
//文件名: urlcode.cpp
#include "urlcode.h"
char url_hextochr(unsigned char n)
{
char ret;
n &= 0x0f;
if(n < 10)
ret = (char)(n + '0');
else
ret = (char)(n - 10 + 'A');
return ret;
}
unsigned char url_chrtohex(char n)
{
unsigned char ret;
if(n <= '9' && n >= '0')
ret = n - '0';
else if(n <= 'F' && n >= 'A')
ret = n - 'A' + 10;
else if(n <= 'f' && n >= 'a')
ret = n - 'a' + 10;
else
ret = 0;
return ret;
}
std::string UrlEncode(char *pchSrc, long iSize)
{
long i;
unsigned char ch,ch1,ch2;
std::string result;
result.erase();
if( iSize == -1)
iSize = strlen(pchSrc);
for(i=0; i<iSize; i++)
{
ch =(unsigned char)(*(pchSrc + i));
if(isalnum(ch))
result.append(1,(char)ch);
else if(ch == ' ')
result.append(1,'+');
else
{
ch1 = ch >> 4;
ch2 = ch & 0x0F;
result.append(1,'%');
result.append(1,(char)url_hextochr(ch1));
result.append(1,(char)url_hextochr(ch2));
}
}
return result;
}
std::string UrlDecode(char *pchSrc, long iSize)
{
long i,right;
char ch;
unsigned char ch1,ch2;
std::string result;
result.erase();
if( iSize == -1)
iSize = strlen(pchSrc);
for(i = 0; i < iSize; i++)
{
ch = *(pchSrc + i);
right = iSize - i -1;
if(isalnum((unsigned char)ch))
result.append(1,ch);
else if(ch == '+')
result.append(1,' ');
else if( ch == '%')
{
if(right < 2)
break;
ch1 = url_chrtohex(*(pchSrc + (++i)));
ch2 = url_chrtohex(*(pchSrc + (++i)));
result.append(1,(char)( (ch1 << 4) | ch2));
}
}
return result;
}
int UrlParse(url_map &hostmap,url_map ¶map,char *purl)
{
char *p, *pos;
std::string value,value1,key,tmp;
p = purl;
if(p == NULL)
return 0;
hostmap.clear();
paramap.clear();
//////////////////////////
//处理协议 如:HTTP
tmp.erase();
pos = strstr(p, "://");
if(pos == NULL)
hostmap.insert(url_value_type("schema", ""));
else
{
value .append(p,pos - p);
hostmap.insert(url_value_type("schema", value));
p = pos + 3;
}
//////////////////////////////////////
//处理用户和口令 如:username:password
tmp.erase();
pos = strstr(p,"@");
if(pos == NULL)
{
hostmap.insert(url_value_type("username", ""));
hostmap.insert(url_value_type("password", ""));
}
else
{
tmp.append(p,pos -p);
int ret = tmp.find(':',0);
if (ret == -1)
{
hostmap.insert(url_value_type("username", ""));
hostmap.insert(url_value_type("password", ""));
}
else
{
value = tmp.substr(0, ret);
value1 = tmp.substr(ret+1);
hostmap.insert(url_value_type("username", value));
hostmap.insert(url_value_type("password", value1));
}
p = pos + 1;
}
///////////////////////////////////////////
//处理 主机和端口 如:host:port 默认端口 80
tmp.erase();
pos = strstr(p, "/");
if(pos == NULL)
{
tmp.append(p);
p += strlen(p);
int ret = tmp.find(":");
if (ret == -1)
{
hostmap.insert(url_value_type("host",tmp));
hostmap.insert(url_value_type("port",""));
}
else
{
value = tmp.substr(0,ret);
value1 = tmp.substr(ret+1);
hostmap.insert(url_value_type("host",value));
hostmap.insert(url_value_type("port",value1));
}
}
else
{
tmp.append(p,pos-p);
p = pos + 1;
int ret = tmp.find(":");
if (ret == -1)
{
hostmap.insert(url_value_type("host",tmp));
hostmap.insert(url_value_type("port",""));
}
else
{
value = tmp.substr(0,ret);
value1 = tmp.substr(ret+1);
hostmap.insert(url_value_type("host",value));
hostmap.insert(url_value_type("port",value1));
}
}
///////////////////////////////////
//处理路径 如:/dir1/dir2/file.name
tmp.erase();
pos = strstr(p,"?");
if(pos == NULL)
{
tmp = "/";
tmp.append(p);
p += strlen(p);
hostmap.insert(url_value_type("path",tmp));
}
else
{
tmp.append("/");
tmp.append(p,pos - p);
p = pos + 1;
hostmap.insert(url_value_type("path",tmp));
}
////////////////////////////////////////////////
// 处理参数
while((pos = strstr(p,"&"))!=NULL)
{
tmp.erase();
tmp.append(p,pos - p);
p = pos + 1;
int ret = tmp.find("=");
if(ret == -1)
continue;
key = tmp.substr(0,ret);
value = tmp.substr(ret + 1);
paramap.insert(url_value_type(key,value));
}
if(pos == NULL && strlen(p) > 0)
{
tmp.erase();
tmp.append(p);
int ret = tmp.find("=");
if(ret != -1)
{
key = tmp.substr(0,ret);
value = tmp.substr(ret + 1);
paramap.insert(url_value_type(key,value));
}
}
return 1;
}