{
/*
This follows the algorithm in section 5.2.4. of RFC3986,
but doesn't modify the input buffer.
*/
CPStringBuilder input = new CPStringBuilder(relativePath);
CPStringBuilder output = new CPStringBuilder();
int start = 0;
while (start < input.length())
{
/* A */
if (input.indexOf("../",start) == start)
{
start += 3;
continue;
}
if (input.indexOf("./",start) == start)
{
start += 2;
continue;
}
/* B */
if (input.indexOf("/./",start) == start)
{
start += 2;
continue;
}
if (input.indexOf("/.",start) == start
&& input.charAt(start + 2) != '.')
{
start += 1;
input.setCharAt(start,'/');
continue;
}
/* C */
if (input.indexOf("/../",start) == start)
{
start += 3;
removeLastSegment(output);
continue;
}
if (input.indexOf("/..",start) == start)
{
start += 2;
input.setCharAt(start,'/');
removeLastSegment(output);
continue;
}
/* D */
if (start == input.length() - 1 && input.indexOf(".",start) == start)
{
input.delete(0,1);
continue;
}
if (start == input.length() - 2 && input.indexOf("..",start) == start)
{
input.delete(0,2);
continue;
}
/* E */
int indexOfSlash = input.indexOf("/",start);
while (indexOfSlash == start)
{
output.append("/");
++start;
indexOfSlash = input.indexOf("/",start);
}
if (indexOfSlash == -1)
indexOfSlash = input.length();
output.append(input.substring(start, indexOfSlash));
start = indexOfSlash;
}
return output.toString();
}