URL解析的C++代码 - 摘自RLib

 备注:C++解析URL除了第三方库之外,还可以使用ParseURL,该函数定义在Shlwapi.h中,美中不足的是,无法解析出端口.

/************************************************************************/
/* Uri                                                                
/************************************************************************/
Uri::Uri(const String &url)
{
//	this->OriginalString = url;

	// parse scheme part
	intptr_t offsetScheme = url.IndexOf(_T("://"));
	if (offsetScheme == -1/* || offsetScheme > 5*/) {
		trace(!"invalid url");
		return;
    }
	this->Scheme = url.Substring(0, offsetScheme - 0).toUpper();

	// the rest part of url
	intptr_t beginOffset   = offsetScheme + RLIB_COUNTOF_STR(_T("://"));
	const String &url_body = url;

	// parse host and port
    intptr_t portOffset  = url_body.IndexOf(_T(":"), beginOffset);
	intptr_t slashOffset = url_body.IndexOf(_T("/"), beginOffset);
    if (portOffset == -1 || (slashOffset !=  -1 && portOffset > slashOffset))
    {
		// not found port or illegal, use default port
		this->Port = (offsetScheme != 5 || this->Scheme != _T("HTTPS")) ? 80 : 443; 
        // check path body
		if (slashOffset == -1) {
			// http:// rlib.cf
            this->Host         = url_body.Substring(beginOffset).toLower();
            this->PathAndQuery = RSTR("/");
        } else {
			// http:// rlib.cf /file?query=...
            this->Host = url_body.Substring(beginOffset, slashOffset - beginOffset).toLower();
            this->PathAndQuery = url_body.Substring(slashOffset);
        }
    }
    else
    {
        this->Host = url_body.Substring(beginOffset, portOffset - beginOffset).toLower();
		// no slash
		// skip ':', so
		portOffset += 1;
		if (slashOffset == -1) {
			// http:// rlib.cf:port		
			this->Port = static_cast<USHORT>(Int32::TryParse(url_body.GetConstData() + portOffset));
			this->PathAndQuery = RSTR("/");
		} else {
			// http:// hostname:port /file?query=...
			String &&strPort   = url_body.Substring(portOffset, slashOffset - portOffset);
			this->Port         = static_cast<USHORT>(Int32::TryParse(strPort));
			this->PathAndQuery = url_body.Substring(slashOffset);
		}
    }
}

//-------------------------------------------------------------------------

String Uri::ProcessUri(const String &path, const Uri *lpfather)
{
	intptr_t offset = path.IndexOf(_T("://"));
    if (offset != -1 && offset < 8){
        return path;
    }

	String url(128);
	url.Append(lpfather->Scheme);
	url.Append(RLIB_STR_LEN(_T("://")));
	url.Append(lpfather->Host);
	url.Append(RLIB_STR_LEN(_T(":")));
	url.Append(Int32(lpfather->Port).ToString());

    if (!path.StartsWith(_T('/'))){
		intptr_t slashOffset = lpfather->PathAndQuery.LastIndexOf(_T('/'));
		url.Append(lpfather->PathAndQuery.GetConstData(), slashOffset + 1 - 0);
    }

	return url;
}

你可能感兴趣的:(c,优化,String,url)