in activemq-cpp/src/main/decaf/net/URLStreamHandler.cpp [185:294]
void URLStreamHandler::parseURL(URL& url, const String& spec, int start, int limit) {
if (limit < start || limit < 0) {
if ((limit <= Integer::MIN_VALUE + 1 && (start >= spec.length() || start < 0)) ||
(spec.startsWith("//", start) && spec.indexOf('/', start + 2) == -1)) {
throw StringIndexOutOfBoundsException(__FILE__, __LINE__, limit);
}
if (this != url.getURLStreamHandler()) {
throw SecurityException(__FILE__, __LINE__, "Only the URL's stream handler can modify");
}
return;
}
int fileStart;
String authority;
String userInfo;
String host;
int port = -1;
String path;
String query;
String ref;
if (spec.regionMatches(start, "//", 0, 2)) {
// Parse the authority from the spec.
int authorityStart = start + 2;
fileStart = URLUtils::findFirstOf(spec, "/?#", authorityStart, limit);
authority = spec.substring(authorityStart, fileStart);
int userInfoEnd = URLUtils::findFirstOf(spec, "@", authorityStart, fileStart);
int hostStart;
if (userInfoEnd != fileStart) {
userInfo = spec.substring(authorityStart, userInfoEnd);
hostStart = userInfoEnd + 1;
} else {
userInfo = "";
hostStart = authorityStart;
}
/*
* Extract the host and port. The host may be an IPv6 address with
* colons like "[::1]", in which case we look for the port delimiter
* colon after the ']' character.
*/
int colonSearchFrom = hostStart;
int ipv6End = URLUtils::findFirstOf(spec, "]", hostStart, fileStart);
if (ipv6End != fileStart) {
if (URLUtils::findFirstOf(spec, ":", hostStart, ipv6End) == ipv6End) {
throw IllegalArgumentException(__FILE__, __LINE__,
(std::string("Expected an IPv6 address: ") +
spec.substring(hostStart, ipv6End + 1).toString()).c_str());
}
colonSearchFrom = ipv6End;
}
int hostEnd = URLUtils::findFirstOf(spec, ":", colonSearchFrom, fileStart);
host = spec.substring(hostStart, hostEnd);
int portStart = hostEnd + 1;
if (portStart < fileStart) {
port = Integer::parseInt(spec.substring(portStart, fileStart).toString());
if (port < 0) {
throw IllegalArgumentException(__FILE__, __LINE__, "port < 0: %d", port);
}
}
path = "";
query = "";
ref = "";
} else {
// Get the authority from the context URL.
fileStart = start;
authority = url.getAuthority();
userInfo = url.getUserInfo();
host = url.getHost();
port = url.getPort();
path = url.getPath();
query = url.getQuery();
ref = url.getRef();
}
/*
* Extract the path, query and fragment. Each part has its own leading
* delimiter character. The query can contain slashes and the fragment
* can contain slashes and question marks.
* / path ? query # fragment
*/
int pos = fileStart;
while (pos < limit) {
int nextPos;
switch (spec.charAt(pos)) {
case '#':
nextPos = limit;
ref = spec.substring(pos + 1, nextPos);
break;
case '?':
nextPos = URLUtils::findFirstOf(spec, "#", pos, limit);
query = spec.substring(pos + 1, nextPos);
ref = "";
break;
default:
nextPos = URLUtils::findFirstOf(spec, "?#", pos, limit);
path = relativePath(path, spec.substring(pos, nextPos));
query = "";
ref = "";
break;
}
pos = nextPos;
}
path = URLUtils::authoritySafePath(authority, path);
setURL(url, url.getProtocol(), host, port, authority, userInfo, path, query, ref);
}