diff options
author | Marco Rossignoli <marco.rossignoli@gmail.com> | 2019-05-28 20:14:05 +0200 |
---|---|---|
committer | Dan Moseley <danmose@microsoft.com> | 2019-05-28 11:14:05 -0700 |
commit | e44730085c65ddb98dad1a3059b4e8f7a1ae33ea (patch) | |
tree | 8a759bc11ea5277f5b4de5734ea63285e07f978b /src/System.Private.CoreLib | |
parent | 89517b04ae89a39b4bde720f8cca87cfa4f12d2e (diff) | |
download | coreclr-e44730085c65ddb98dad1a3059b4e8f7a1ae33ea.tar.gz coreclr-e44730085c65ddb98dad1a3059b4e8f7a1ae33ea.tar.bz2 coreclr-e44730085c65ddb98dad1a3059b4e8f7a1ae33ea.zip |
Expose Path.TrimEndingDirectorySeparator (#20805)
* expose TrimEndingDirectorySeparator
* address PR feedback
* updates
* address PR feedback
* fix comment
Diffstat (limited to 'src/System.Private.CoreLib')
5 files changed, 50 insertions, 43 deletions
diff --git a/src/System.Private.CoreLib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs b/src/System.Private.CoreLib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs index 602537a305..7adc7d019c 100644 --- a/src/System.Private.CoreLib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs +++ b/src/System.Private.CoreLib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs @@ -52,7 +52,7 @@ namespace Microsoft.Win32.SafeHandles bool isDirectory = (error.Error == Interop.Error.ENOENT) && ((flags & Interop.Sys.OpenFlags.O_CREAT) != 0 - || !DirectoryExists(Path.GetDirectoryName(PathInternal.TrimEndingDirectorySeparator(path!))!)); + || !DirectoryExists(Path.GetDirectoryName(Path.TrimEndingDirectorySeparator(path!))!)); Interop.CheckIo( error.Error, diff --git a/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs b/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs index 71a986eeef..16bd3b4130 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs @@ -248,31 +248,26 @@ namespace System.IO if (root.Length == 0) return root; - int offset = GetUncRootLength(path); - if (offset >= 0) + // Cut from "\\?\UNC\Server\Share" to "Server\Share" + // Cut from "\\Server\Share" to "Server\Share" + int startOffset = GetUncRootLength(path); + if (startOffset == -1) { - // Cut from "\\?\UNC\Server\Share" to "Server\Share" - // Cut from "\\Server\Share" to "Server\Share" - return TrimEndingDirectorySeparator(root.Slice(offset)); - } - else if (PathInternal.IsDevice(path)) - { - return TrimEndingDirectorySeparator(root.Slice(4)); // Cut from "\\?\C:\" to "C:" + if (PathInternal.IsDevice(path)) + { + startOffset = 4; // Cut from "\\?\C:\" to "C:" + } + else + { + startOffset = 0; // e.g. "C:" + } } - return TrimEndingDirectorySeparator(root); // e.g. "C:" + ReadOnlySpan<char> pathToTrim = root.Slice(startOffset); + return Path.EndsInDirectorySeparator(pathToTrim) ? pathToTrim.Slice(0, pathToTrim.Length - 1) : pathToTrim; } /// <summary> - /// Trims the ending directory separator if present. - /// </summary> - /// <param name="path"></param> - internal static ReadOnlySpan<char> TrimEndingDirectorySeparator(ReadOnlySpan<char> path) => - PathInternal.EndsInDirectorySeparator(path) ? - path.Slice(0, path.Length - 1) : - path; - - /// <summary> /// Returns offset as -1 if the path is not in Unc format, otherwise returns the root length. /// </summary> /// <param name="path"></param> diff --git a/src/System.Private.CoreLib/shared/System/IO/Path.cs b/src/System.Private.CoreLib/shared/System/IO/Path.cs index b0c3df3416..7412eb6278 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Path.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Path.cs @@ -541,7 +541,7 @@ namespace System.IO return true; } - bool needsSeparator = !(PathInternal.EndsInDirectorySeparator(path1) || PathInternal.StartsWithDirectorySeparator(path2)); + bool needsSeparator = !(EndsInDirectorySeparator(path1) || PathInternal.StartsWithDirectorySeparator(path2)); int charsNeeded = path1.Length + path2.Length + (needsSeparator ? 1 : 0); if (destination.Length < charsNeeded) return false; @@ -569,8 +569,8 @@ namespace System.IO if (path3.Length == 0) return TryJoin(path1, path2, destination, out charsWritten); - int neededSeparators = PathInternal.EndsInDirectorySeparator(path1) || PathInternal.StartsWithDirectorySeparator(path2) ? 0 : 1; - bool needsSecondSeparator = !(PathInternal.EndsInDirectorySeparator(path2) || PathInternal.StartsWithDirectorySeparator(path3)); + int neededSeparators = EndsInDirectorySeparator(path1) || PathInternal.StartsWithDirectorySeparator(path2) ? 0 : 1; + bool needsSecondSeparator = !(EndsInDirectorySeparator(path2) || PathInternal.StartsWithDirectorySeparator(path3)); if (needsSecondSeparator) neededSeparators++; @@ -831,10 +831,10 @@ namespace System.IO // Trailing separators aren't significant for comparison int relativeToLength = relativeTo.Length; - if (PathInternal.EndsInDirectorySeparator(relativeTo.AsSpan())) + if (EndsInDirectorySeparator(relativeTo.AsSpan())) relativeToLength--; - bool pathEndsInSeparator = PathInternal.EndsInDirectorySeparator(path.AsSpan()); + bool pathEndsInSeparator = EndsInDirectorySeparator(path.AsSpan()); int pathLength = path.Length; if (pathEndsInSeparator) pathLength--; @@ -903,5 +903,33 @@ namespace System.IO StringComparison.OrdinalIgnoreCase; } } + + /// <summary> + /// Trims one trailing directory separator beyond the root of the path. + /// </summary> + public static string TrimEndingDirectorySeparator(string path) => + EndsInDirectorySeparator(path) && !PathInternal.IsRoot(path.AsSpan()) ? + path.Substring(0, path.Length - 1) : + path; + + /// <summary> + /// Trims one trailing directory separator beyond the root of the path. + /// </summary> + public static ReadOnlySpan<char> TrimEndingDirectorySeparator(ReadOnlySpan<char> path) => + EndsInDirectorySeparator(path) && !PathInternal.IsRoot(path) ? + path.Slice(0, path.Length - 1) : + path; + + /// <summary> + /// Returns true if the path ends in a directory separator. + /// </summary> + public static bool EndsInDirectorySeparator(ReadOnlySpan<char> path) + => path.Length > 0 && PathInternal.IsDirectorySeparator(path[path.Length - 1]); + + /// <summary> + /// Returns true if the path ends in a directory separator. + /// </summary> + public static bool EndsInDirectorySeparator(string path) + => path != null && path.Length > 0 && PathInternal.IsDirectorySeparator(path[path.Length - 1]); } } diff --git a/src/System.Private.CoreLib/shared/System/IO/PathInternal.cs b/src/System.Private.CoreLib/shared/System/IO/PathInternal.cs index c6e1de46c8..3b864ac14c 100644 --- a/src/System.Private.CoreLib/shared/System/IO/PathInternal.cs +++ b/src/System.Private.CoreLib/shared/System/IO/PathInternal.cs @@ -11,28 +11,12 @@ namespace System.IO internal static partial class PathInternal { /// <summary> - /// Returns true if the path ends in a directory separator. - /// </summary> - internal static bool EndsInDirectorySeparator(ReadOnlySpan<char> path) - => path.Length > 0 && IsDirectorySeparator(path[path.Length - 1]); - - /// <summary> /// Returns true if the path starts in a directory separator. /// </summary> internal static bool StartsWithDirectorySeparator(ReadOnlySpan<char> path) => path.Length > 0 && IsDirectorySeparator(path[0]); internal static string EnsureTrailingSeparator(string path) - => EndsInDirectorySeparator(path.AsSpan()) ? path : path + DirectorySeparatorCharAsString; - - internal static string TrimEndingDirectorySeparator(string path) => - EndsInDirectorySeparator(path.AsSpan()) && !IsRoot(path.AsSpan()) ? - path.Substring(0, path.Length - 1) : - path; - - internal static ReadOnlySpan<char> TrimEndingDirectorySeparator(ReadOnlySpan<char> path) => - EndsInDirectorySeparator(path) && !IsRoot(path) ? - path.Slice(0, path.Length - 1) : - path; + => Path.EndsInDirectorySeparator(path.AsSpan()) ? path : path + DirectorySeparatorCharAsString; internal static bool IsRoot(ReadOnlySpan<char> path) => path.Length == GetRootLength(path); diff --git a/src/System.Private.CoreLib/src/System/AppContext.CoreCLR.cs b/src/System.Private.CoreLib/src/System/AppContext.CoreCLR.cs index 93bef4e180..84313e341e 100644 --- a/src/System.Private.CoreLib/src/System/AppContext.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/AppContext.CoreCLR.cs @@ -21,7 +21,7 @@ namespace System { // Fallback path for hosts that do not set APP_CONTEXT_BASE_DIRECTORY explicitly string? directory = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location); - if (directory != null && !PathInternal.EndsInDirectorySeparator(directory)) + if (directory != null && !Path.EndsInDirectorySeparator(directory)) directory += Path.DirectorySeparatorChar; return directory; } |