首页
社区
课程
招聘
[原创]uriScheme类实现的简单版本[URI资料解析类]。
发表于: 2013-10-6 13:02 7756

[原创]uriScheme类实现的简单版本[URI资料解析类]。

2013-10-6 13:02
7756
上午发了一篇文章讲解解析URL小技巧,但aqtata大侠发了一个标准文档出来,于是根据标准文档编写代码,花了几个小时,写了一个简单版本的uri Scheme,接下来请看代码。
原文地址:http://bbs.pediy.com/showthread.php?t=179681
PS:只负责解析标准的HTTPS、HTTP链接,其他的链接如果崩溃了一律不负责。
void testScheme() {
	Scheme::uriScheme* uri = new Scheme::uriScheme("foo://example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose");
	printf("%s\r\n", uri->getSchemeName());
	printf("%s\r\n", uri->getHostName());
	printf("%s\r\n", uri->getHostPort());
	printf("%s\r\n", uri->getInfoPath());
	printf("%s\r\n", uri->getQueueInfo());
	printf("%s\r\n", uri->getFragment());
	delete uri;
补充一下:
以上依次输出:foo、example.com、8042(如果没有端口默认80、443,这是标准的端口)、/over/there/index.dtb、type=animal&name=narwhal、nose
}


uriScheme.h
/*
 * uriScheme.h
 *
 *  Created on: Oct 5, 2013
 *      Author: vscen
 */

#ifndef URISCHEME_H_
#define URISCHEME_H_

#include "xxxxxxxx.h"

namespace Scheme {
class uriScheme {
	char* uri_;
	size_t urilen_;
public:
	explicit uriScheme(const char* uri);
	virtual ~uriScheme();
	const char* getSchemeName();
	const char* getHostName();
	const char* getHostPort();
	const char* getInfoPath();
	const char* getQueueInfo();
	const char* getFragment();
private:
	bool createsUriScheme(const char* uri);
	void destroyUriScheme();
	bool isEmptyUriScheme() const;
	size_t getUriLength() const;
	const char* getUriString() const;
	bool parsedSchemeName();
	bool parsedHostName();
	bool parsedHostPort();
	bool parsedInfoPath();
	bool parsedQueueInfo();
	bool parsedFragment();
};
}


uriScheme.cc
/*
 * uriScheme.cc
 *
 *  Created on: Oct 5, 2013
 *      Author: vscen
 */

#include "uriScheme.h"

namespace Scheme {
namespace uriSchemeConst {
char* kPos = NULL;
const unsigned long kMaxUriScheme = 1024;
char kSchemeName[kMaxUriScheme] = { 0 };
char kHostName[kMaxUriScheme] = { 0 };
char kHostPort[kMaxUriScheme] = { 0 };
char kInfoPath[kMaxUriScheme] = { 0 };
char kQueueInfo[kMaxUriScheme] = { 0 };
char kFragment[kMaxUriScheme] = { 0 };
}

uriScheme::uriScheme(const char* uri) {
	if (uriScheme::createsUriScheme(uri)) {
		uriScheme::parsedSchemeName();
		uriScheme::parsedHostName();
		uriScheme::parsedHostPort();
		uriScheme::parsedInfoPath();
		uriScheme::parsedQueueInfo();
		uriScheme::parsedFragment();
	}

}
uriScheme::~uriScheme() {
	uriScheme::destroyUriScheme();
}

const char* uriScheme::getSchemeName() {
	return (uriSchemeConst::kSchemeName);
}

const char* uriScheme::getHostName() {
	return (uriSchemeConst::kHostName);
}

const char* uriScheme::getHostPort() {
	return (uriSchemeConst::kHostPort);
}

const char* uriScheme::getInfoPath() {
	return (uriSchemeConst::kInfoPath);
}

const char* uriScheme::getQueueInfo() {
	return (uriSchemeConst::kQueueInfo);
}

const char* uriScheme::getFragment() {
	return (uriSchemeConst::kFragment);
}

bool uriScheme::createsUriScheme(const char* uri) {
	uriScheme::urilen_ = strlen(uri);
	uriScheme::uri_ = (char*) malloc(uriScheme::getUriLength() + 1);
	if (!uriScheme::isEmptyUriScheme()) {
		return false;
	} else {
		memcpy(uriScheme::uri_, uri, uriScheme::getUriLength());
		uriScheme::uri_[uriScheme::getUriLength()] = 0;
		uriSchemeConst::kPos = uriScheme::uri_;
		return (uriScheme::getUriLength() < uriSchemeConst::kMaxUriScheme);
	}
}

void uriScheme::destroyUriScheme() {
	if (uriScheme::isEmptyUriScheme()) {
		free(uriScheme::uri_);
		uriScheme::urilen_ = 0;
		uriSchemeConst::kPos = NULL;
	}
}

bool uriScheme::isEmptyUriScheme() const {
	return (uriScheme::getUriString() != NULL && uriScheme::getUriLength() > 0);
}

size_t uriScheme::getUriLength() const {
	return (uriScheme::urilen_);
}

const char* uriScheme::getUriString() const {
	return (uriScheme::uri_);
}

bool uriScheme::parsedSchemeName() {
	char* buf = uriSchemeConst::kPos;
	if (buf == NULL) {
		return false;
	} else {
		int i = 0;
		for (i = 0; *buf != 0; buf++, i++) {
			uriSchemeConst::kSchemeName[i] = *buf;
			if (isalpha(*buf)) {
				continue;
			} else if (isdigit(*buf)) {
				continue;
			} else if (*buf == '+' || *buf == '.' || *buf == '-') {
				continue;
			} else if (*buf == ':') {
				break;
			} else {
				return false;
			}
		}
		uriSchemeConst::kSchemeName[i] = 0;
		uriSchemeConst::kPos = buf;
		return true;
	}
}

bool uriScheme::parsedHostName() {
	char* buf = uriSchemeConst::kPos;
	if (buf == NULL || strncmp(buf, "://", 3) != 0) {
		return false;
	} else {
		buf += 3;
		int i = 0;
		for (i = 0; *buf != 0; buf++, i++) {
			uriSchemeConst::kHostName[i] = *buf;
			if (*buf == ':' || *buf == '/') {
				break;
			}
		}
		uriSchemeConst::kHostName[i] = 0;
		uriSchemeConst::kPos = buf;
		return true;
	}
}

bool uriScheme::parsedHostPort() {
	char* buf = uriSchemeConst::kPos;
	if (buf == NULL || *buf != ':') {
		if (strncasecmp(uriSchemeConst::kSchemeName, "http", 4) == 0) {
			strncat(uriSchemeConst::kHostPort, "80\0", 3);
			return true;
		} else if (strncasecmp(uriSchemeConst::kSchemeName, "https", 5) == 0) {
			strncat(uriSchemeConst::kHostPort, "443\0", 4);
			return true;
		} else {
			return false;
		}
	} else {
		buf += 1;
		int i = 0;
		for (i = 0; *buf != 0; buf++, i++) {
			uriSchemeConst::kHostPort[i] = *buf;
			if (*buf == '/') {
				break;
			}
		}
		uriSchemeConst::kHostPort[i] = 0;
		uriSchemeConst::kPos = buf;
		return true;
	}
}

bool uriScheme::parsedInfoPath() {
	char* buf = uriSchemeConst::kPos;
	if (buf == NULL || *buf != '/') {
		return false;
	} else {
		int i = 0;
		for (i = 0; *buf != 0; buf++, i++) {
			uriSchemeConst::kInfoPath[i] = *buf;
			if ((*buf == '/') && (*(buf + 1) == 0)) {
				break;
			} else if (*buf == '?') {
				break;
			} else {
				continue;
			}
		}
		uriSchemeConst::kInfoPath[i] = 0;
		uriSchemeConst::kPos = buf;
		return true;
	}

}

bool uriScheme::parsedQueueInfo() {
	char* buf = uriSchemeConst::kPos;
	if (buf == NULL || *buf != '?') {
		return false;
	} else {
		buf += 1;
		int i = 0;
		for (i = 0; *buf != 0; buf++, i++) {
			uriSchemeConst::kQueueInfo[i] = *buf;
			if (*buf == '#') {
				break;
			} else {
				continue;
			}
		}
		uriSchemeConst::kQueueInfo[i] = 0;
		uriSchemeConst::kPos = buf;
		return true;
	}
}

bool uriScheme::parsedFragment() {
	char* buf = uriSchemeConst::kPos;
	if (buf == NULL || *buf != '#') {
		return false;
	} else {
		buf += 1;
		int i = 0;
		for (i = 0; *buf != 0; buf++, i++) {
			uriSchemeConst::kFragment[i] = *buf;
			continue;
		}
		uriSchemeConst::kFragment[i] = 0;
		uriSchemeConst::kPos = buf;
		return true;
	}
}
}

[课程]Android-CTF解题方法汇总!

收藏
免费 5
支持
分享
最新回复 (6)
雪    币: 80
活跃值: (109)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
可以见得楼主是个很牛的程序猿——这么快就写了这个玩意。
感谢楼主,东西不错。先收藏。

不知xxxxxxxx.h是什么……
2013-10-6 13:17
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
3
自己的头文件,没必要发上来吧,自己把标准的C库添加上去就成了。
2013-10-6 13:18
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
4
123456
2013-10-6 23:45
0
雪    币: 357
活跃值: (3123)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
5
重复单词uriScheme, uriSchemeConst 太多
if,else,for 也多,有点乱
在循环末尾用了continue,没必要
2013-10-7 00:50
0
雪    币: 142
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不错哟
不过你没考虑不带协议头的路径哟
如果测试example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose
输出会变成神马?
反斜杠的也没处理,测试example.com:8042\over\there\index.dtb?type=animal&name=narwhal#nose
看看输出又是神马...

就算不用Windows,其他平台也有各种字符串查找,取left,mid,right函数吧,楼主好好的函数不用,然后非得一个个字符匹配,结果还丢这丢那的...
2013-10-7 10:02
0
雪    币: 239
活跃值: (190)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
7
多线程同时调用
看看输出又是神马
2013-10-7 12:00
0
游客
登录 | 注册 方可回帖
返回
//