您当前的位置: 首页 >  算法

qianbo_insist

暂无认证

  • 0浏览

    0关注

    399博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

c++ 高效解析url算法

qianbo_insist 发布时间:2021-06-10 19:58:20 ,浏览量:0

协议解析url 用处

http协议,rtp协议,rtmp协议,rtsp中解析url,很多语言都有封装的解析URL的工具类库,在c++ 写的server的中如果需要解析url,需要写一个高效率的解析封装方法。这里使用c++,仅仅使用c++ STL 的string 类 以及c++的封装特性,解析尽量使用了c的方式,以便于改进。

比较和查找

在url中查找字符串,如?,&,等等

static inline int judge_equeal(const char *pos, const char *compare, size_t &clen)
{
	for (size_t i = 0; i  ulen)
		return -1;
	const char *pos = u;
	const char *posend = u + ulen - 1;
	for (; pos  ulen)
		return NULL;
	const char *pos = u;
	const char *posend = u + ulen - 1;
	for (; pos =0)
		{
			param.host = string(pos, point);
			pos += point + 1;
			string tmp = string(pos, posend - pos) ;
			if(IsNumber(tmp.c_str()))
				param.port = atoi(tmp.c_str());
			return 0;
		}
		return -1;
	}
	static bool IsNumber(const char * num)
	{
		int length = (int)strlen(num);
		for (int i = 0; i  1)
					continue;
				return false;
			}
			if (!isdigit(num[i]))
				return false;
		}
		return true;
	}
public:
	TParseUrl(const char * url) {
		ParseUrl(url, v_param);
	}
	virtual ~TParseUrl() {};
	TUrlParam v_param;

#define POS_JUDGE if(pos>=posend) return -1
#define POS_JUDGE_OK if(pos>=posend) return 0
	static int ParseUrl(const char *url, TUrlParam ¶m)
	{
		//memset(¶m, 0, sizeof(param));
		const char * posend = url + strlen(url) - 1;
		param.uri = url;
		const char * pos = url;
		int point = 0;
		if ((point = string_find(pos, "://")) >= 0)
		{
			param.protocol = string(url, point);
		}
		else
			return -1;
		pos += point + 3; //strlen("://")
		POS_JUDGE;
		if ((point = string_find(pos, "/")) >= 0)
		{
			param.host = string(pos, point);
			const char *end = pos + point;
			parse_domain(pos, end, param);
			param.uri = string(pos + point + 1);
		}
		else
		{
			//the left all is domain
			int hlen = (int)(posend - pos + 1);
			param.host = string(pos,hlen);
			const char *end = pos + hlen - 1;
			parse_domain(pos, end, param);
			param.uri = "/";
			return 0;
		}


	
		return 0;
	}

	string GetParam(const char *param)
	{
		int point = -1;
		const char *ustart = v_param.uri.c_str();

		const char * start = string_find_pos(ustart, "?");
		if (start != NULL)
		{
			++start;
			//?a=abc&b=ddd
			string par = param;
			par +="=";
			start = string_find_pos(start, par.c_str());
			if (start != NULL )
			{
				const char * j = start - 1;
				char c = *j;
				if (c == '&' || c == '?')
				{
					start += par.length();
					const char * end = string_find_pos(start, "&");
					if (end != NULL)
					{
						return string(start, end);
					}
					return string(start);
				}
			}
		}
		return "";
	}

	void SetUrl(const char *url)
	{
		v_param.clear();
		ParseUrl(url, v_param);
	}
};
调用

在GetParam的时候,如果没有

if (c == ‘&’ || c == ‘?’)

的判断是不行的,为了加快判决我们直接是模式匹配,但是有如 “abc=” 如果不小心把“c=” 的模式配置在url中查找到就去取值是不对的,判断前一个字节是?或者& 是明智的做法。

int main()
{
cout             
关注
打赏
1663161521
查看更多评论
0.0384s