using System; using System.IO; namespace TrackedFolders.Utilities { /// /// Various extensions for dealing with subpaths. /// /// https://stackoverflow.com/questions/5617320/given-full-path-check-if-path-is-subdirectory-of-some-other-path-or-otherwise public static class Subpaths { #region Public Methods public static string NormalizePath(this string path) { return Path.GetFullPath(path.Replace('/', '\\') .WithEnding("\\")); } /// /// Returns true if starts with the path . /// The comparison is case-insensitive, handles / and \ slashes as folder separators and /// only matches if the base dir folder name is matched exactly ("c:\foobar\file.txt" is not a sub path of "c:\foo"). /// public static bool IsSubPathOf(this string path, string baseDirPath) { var normalizedPath = NormalizePath(path); var normalizedBaseDirPath = NormalizePath(baseDirPath); return normalizedPath.StartsWith(normalizedBaseDirPath, StringComparison.OrdinalIgnoreCase); } public static bool IsPathEqual(this string path, string that) { return string.Equals(NormalizePath(path), NormalizePath(that), StringComparison.OrdinalIgnoreCase); } #endregion #region Private Methods /// /// Returns with the minimal concatenation of (starting from end) /// that /// results in satisfying .EndsWith(ending). /// /// "hel".WithEnding("llo") returns "hello", which is the result of "hel" + "lo". private static string WithEnding(this string str, string ending) { if (str == null) { return ending; } var result = str; // Right() is 1-indexed, so include these cases // * Append no characters // * Append up to N characters, where N is ending length for (var i = 0; i <= ending.Length; i++) { var tmp = result + ending.Right(i); if (tmp.EndsWith(ending)) { return tmp; } } return result; } /// Gets the rightmost characters from a string. /// The string to retrieve the substring from. /// The number of characters to retrieve. /// The substring. private static string Right(this string value, int length) { if (value == null) { throw new ArgumentNullException("value"); } if (length < 0) { throw new ArgumentOutOfRangeException("length", length, "Length is less than zero"); } return length < value.Length ? value.Substring(value.Length - length) : value; } #endregion } }