public static string NormalizeRelativePath(string relative, bool forceTrailingSlash = false) { if (string.IsNullOrEmpty(relative)) { throw new System.ArgumentException("Empty or null", "relative"); } StringBuilder output = new StringBuilder(relative.Length); NormalizeState state = NormalizeState.PrevSlash; output.Append('/'); int startIndex = 0; int lastIndexPlus1 = relative.Length; if (relative[0] == '"' && relative.Length > 2 && relative[relative.Length - 1] == '"') { startIndex++; lastIndexPlus1--; } for (int i = startIndex; i <= lastIndexPlus1; ++i) { if (i == lastIndexPlus1 || relative[i] == '/' || relative[i] == '\\') { if (state == NormalizeState.PrevSlash || state == NormalizeState.PrevDot) { // do nothing } else if (state == NormalizeState.PrevDoubleDot) { if (output.Length == 1) { throw new System.IO.IOException("Invalid path: double dot error (before " + i + ")"); } // on level up! int j; for (j = output.Length - 2; j >= 0 && output[j] != '/'; --j) { } output.Remove(j + 1, output.Length - j - 1); } else if (i < lastIndexPlus1 || forceTrailingSlash) { output.Append('/'); } state = NormalizeState.PrevSlash; } else if (relative[i] == '.') { if (state == NormalizeState.PrevSlash) { state = NormalizeState.PrevDot; } else if (state == NormalizeState.PrevDot) { state = NormalizeState.PrevDoubleDot; } else if (state == NormalizeState.PrevDoubleDot) { state = NormalizeState.NothingSpecial; output.Append("..."); } else { output.Append('.'); } } else { if (state == NormalizeState.PrevDot) { output.Append('.'); } else if (state == NormalizeState.PrevDoubleDot) { output.Append(".."); } if (!IsValidCharacter(relative[i])) { throw new System.IO.IOException("Invalid characters"); } output.Append(relative[i]); state = NormalizeState.NothingSpecial; } } return(output.ToString()); }
public static string NormalizeRelativePath(string relative, bool forceTrailingSlash = false) { if (string.IsNullOrEmpty(relative)) { throw new System.ArgumentException("Empty or null", "relative"); } StringBuilder output = new StringBuilder(relative.Length); NormalizeState state = NormalizeState.PrevSlash; output.Append('/'); for (int i = 0; i <= relative.Length; ++i) { if (i == relative.Length || relative[i] == Path.DirectorySeparatorChar || relative[i] == Path.AltDirectorySeparatorChar) { if (state == NormalizeState.PrevSlash || state == NormalizeState.PrevDot) { // do nothing } else if (state == NormalizeState.PrevDoubleDot) { if (output.Length == 1) { throw new System.IO.IOException("AAA"); } // on level up! int j; for (j = output.Length - 2; j >= 0 && output[j] != '/'; --j) { } output.Remove(j + 1, output.Length - j - 1); } else if (i < relative.Length || forceTrailingSlash) { output.Append('/'); } state = NormalizeState.PrevSlash; } else if (relative[i] == '.') { if (state == NormalizeState.PrevSlash) { state = NormalizeState.PrevDot; } else if (state == NormalizeState.PrevDot) { state = NormalizeState.PrevDoubleDot; } else if (state == NormalizeState.PrevDoubleDot) { state = NormalizeState.NothingSpecial; output.Append("..."); } else { output.Append('.'); } } else { if (state == NormalizeState.PrevDot) { output.Append('.'); } else if (state == NormalizeState.PrevDoubleDot) { output.Append(".."); } if (!IsValidCharacter(relative[i])) { throw new System.IO.IOException("Invalid characters"); } output.Append(relative[i]); state = NormalizeState.NothingSpecial; } } return(output.ToString()); }