⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uri.cpp

📁 C++ class libraries for network-centric, portable applications, integrated perfectly with the C++ St
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			if (relativeURI._path.empty())			{				if (!relativeURI._query.empty())					_query = relativeURI._query;			}			else			{				if (relativeURI._path[0] == '/')				{					_path = relativeURI._path;					removeDotSegments();				}				else				{					mergePath(relativeURI._path);				}				_query = relativeURI._query;			}		}	}	_fragment = relativeURI._fragment;	}bool URI::isRelative() const{	return _scheme.empty();}bool URI::empty() const{	return _scheme.empty() && _host.empty() && _path.empty() && _query.empty() && _fragment.empty();}	bool URI::operator == (const URI& uri) const{	return equals(uri);}bool URI::operator == (const std::string& uri) const{	URI parsedURI(uri);	return equals(parsedURI);}bool URI::operator != (const URI& uri) const{	return !equals(uri);}bool URI::operator != (const std::string& uri) const{	URI parsedURI(uri);	return !equals(parsedURI);}bool URI::equals(const URI& uri) const{	return _scheme   == uri._scheme	    && _userInfo == uri._userInfo	    && _host     == uri._host	    && getPort() == uri.getPort()	    && _path     == uri._path	    && _query    == uri._query	    && _fragment == uri._fragment;}	void URI::normalize(){	removeDotSegments(!isRelative());}void URI::removeDotSegments(bool removeLeading){	if (_path.empty()) return;		bool leadingSlash  = *(_path.begin()) == '/';	bool trailingSlash = *(_path.rbegin()) == '/';	std::vector<std::string> segments;	std::vector<std::string> normalizedSegments;	getPathSegments(segments);	for (std::vector<std::string>::const_iterator it = segments.begin(); it != segments.end(); ++it)	{		if (*it == "..")		{			if (!normalizedSegments.empty())			{				if (normalizedSegments.back() == "..")					normalizedSegments.push_back(*it);				else					normalizedSegments.pop_back();			}			else if (!removeLeading)			{				normalizedSegments.push_back(*it);			}		}		else if (*it != ".")		{			normalizedSegments.push_back(*it);		}	}	buildPath(normalizedSegments, leadingSlash, trailingSlash);}void URI::getPathSegments(std::vector<std::string>& segments){	getPathSegments(_path, segments);}void URI::getPathSegments(const std::string& path, std::vector<std::string>& segments){	std::string::const_iterator it  = path.begin();	std::string::const_iterator end = path.end();	std::string seg;	while (it != end)	{		if (*it == '/')		{			if (!seg.empty())			{				segments.push_back(seg);				seg.clear();			}		}		else seg += *it;		++it;	}	if (!seg.empty())		segments.push_back(seg);}void URI::encode(const std::string& str, const std::string& reserved, std::string& encodedStr){	for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)	{		char c = *it;		if (c >= 'a' && c <= 'z' || 		    c >= 'A' && c <= 'Z' || 		    c >= '0' && c <= '9' ||		    c == '-' || c == '_' || 		    c == '.' || c == '~')		{			encodedStr += c;		}		else if (c <= 0x20 || c >= 0x7F || ILLEGAL.find(c) != std::string::npos || reserved.find(c) != std::string::npos)		{			encodedStr += '%';			encodedStr += NumberFormatter::formatHex((unsigned) (unsigned char) c, 2);		}		else encodedStr += c;	}}	void URI::decode(const std::string& str, std::string& decodedStr){	std::string::const_iterator it  = str.begin();	std::string::const_iterator end = str.end();	while (it != end)	{		char c = *it++;		if (c == '%')		{			if (it == end) throw SyntaxException("URI encoding: no hex digit following percent sign", str);			char hi = *it++;			if (it == end) throw SyntaxException("URI encoding: two hex digits must follow percent sign", str);			char lo = *it++;			if (hi >= '0' && hi <= '9')				c = hi - '0';			else if (hi >= 'A' && hi <= 'F')				c = hi - 'A' + 10;			else if (hi >= 'a' && hi <= 'f')				c = hi - 'a' + 10;			else throw SyntaxException("URI encoding: not a hex digit");			c *= 16;			if (lo >= '0' && lo <= '9')				c += lo - '0';			else if (lo >= 'A' && lo <= 'F')				c += lo - 'A' + 10;			else if (lo >= 'a' && lo <= 'f')				c += lo - 'a' + 10;			else throw SyntaxException("URI encoding: not a hex digit");		}		decodedStr += c;	}}bool URI::isWellKnownPort() const{	return _port == getWellKnownPort();}unsigned short URI::getWellKnownPort() const{	if (_scheme == "ftp")		return 21;	else if (_scheme == "ssh")		return 22;	else if (_scheme == "telnet")		return 23;	else if (_scheme == "http")		return 80;	else if (_scheme == "nntp")		return 119;	else if (_scheme == "ldap")		return 389;	else if (_scheme == "https")		return 443;	else		return 0;}void URI::parse(const std::string& uri){	std::string::const_iterator it  = uri.begin();	std::string::const_iterator end = uri.end();	if (it == end) return;	if (*it != '/' && *it != '.' && *it != '?' && *it != '#')	{		std::string scheme;		while (it != end && *it != ':' && *it != '?' && *it != '#' && *it != '/') scheme += *it++;		if (it != end && *it == ':')		{			++it;			if (it == end) throw SyntaxException("URI scheme must be followed by authority or path", uri);			setScheme(scheme);			if (*it == '/')			{				++it;				if (it != end && *it == '/')				{					++it;					parseAuthority(it, end);				}				else --it;			}			parsePathEtc(it, end);		}		else 		{			it = uri.begin();			parsePathEtc(it, end);		}	}	else parsePathEtc(it, end);}void URI::parseAuthority(std::string::const_iterator& it, const std::string::const_iterator& end){	std::string userInfo;	std::string part;	while (it != end && *it != '/' && *it != '?' && *it != '#')	{		if (*it == '@')		{			userInfo = part;			part.clear();		}		else part += *it;		++it;	}	std::string::const_iterator pbeg = part.begin();	std::string::const_iterator pend = part.end();	parseHostAndPort(pbeg, pend);	_userInfo = userInfo;}void URI::parseHostAndPort(std::string::const_iterator& it, const std::string::const_iterator& end){	if (it == end) return;	std::string host;	if (*it == '[')	{		// IPv6 address		while (it != end && *it != ']') host += *it++;		if (it == end) throw SyntaxException("unterminated IPv6 address");		host += *it++;	}	else	{		while (it != end && *it != ':') host += *it++;	}	if (it != end && *it == ':')	{		++it;		std::string port;		while (it != end) port += *it++;		if (!port.empty())		{			int nport = 0;			if (NumberParser::tryParse(port, nport) && nport > 0 && nport < 65536)				_port = (unsigned short) nport;			else				throw SyntaxException("bad or invalid port number", port);		}		else _port = getWellKnownPort();	}	else _port = getWellKnownPort();	_host = host;	toLowerInPlace(_host);}void URI::parsePath(std::string::const_iterator& it, const std::string::const_iterator& end){	std::string path;	while (it != end && *it != '?' && *it != '#') path += *it++;	decode(path, _path);}void URI::parsePathEtc(std::string::const_iterator& it, const std::string::const_iterator& end){	if (it == end) return;	if (*it != '?' && *it != '#')		parsePath(it, end);	if (it != end && *it == '?')	{		++it;		parseQuery(it, end);	}	if (it != end && *it == '#')	{		++it;		parseFragment(it, end);	}	}void URI::parseQuery(std::string::const_iterator& it, const std::string::const_iterator& end){	_query.clear();	while (it != end && *it != '#') _query += *it++;}void URI::parseFragment(std::string::const_iterator& it, const std::string::const_iterator& end){	std::string fragment;	while (it != end) fragment += *it++;	decode(fragment, _fragment);}void URI::mergePath(const std::string& path){	std::vector<std::string> segments;	std::vector<std::string> normalizedSegments;	bool addLeadingSlash = false;	if (!_path.empty())	{		getPathSegments(segments);		bool endsWithSlash = *(_path.rbegin()) == '/';		if (!endsWithSlash && !segments.empty())			segments.pop_back();		addLeadingSlash = _path[0] == '/';	}	getPathSegments(path, segments);	addLeadingSlash = addLeadingSlash || !path.empty() && path[0] == '/';	bool hasTrailingSlash = !path.empty() && *(path.rbegin()) == '/';	bool addTrailingSlash = false;	for (std::vector<std::string>::const_iterator it = segments.begin(); it != segments.end(); ++it)	{		if (*it == "..")		{			addTrailingSlash = true;			if (!normalizedSegments.empty())				normalizedSegments.pop_back();		}		else if (*it != ".")		{			addTrailingSlash = false;			normalizedSegments.push_back(*it);		}		else addTrailingSlash = true;	}	buildPath(normalizedSegments, addLeadingSlash, hasTrailingSlash || addTrailingSlash);}void URI::buildPath(const std::vector<std::string>& segments, bool leadingSlash, bool trailingSlash){	_path.clear();	bool first = true;	for (std::vector<std::string>::const_iterator it = segments.begin(); it != segments.end(); ++it)	{		if (first)		{			first = false;			if (leadingSlash)				_path += '/';			else if (_scheme.empty() && (*it).find(':') != std::string::npos)				_path.append("./");		}		else _path += '/';		_path.append(*it);	}	if (trailingSlash) 		_path += '/';}} // namespace Poco

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -