summaryrefslogtreecommitdiff
path: root/src/System.Private.CoreLib
diff options
context:
space:
mode:
authorMarco Rossignoli <marco.rossignoli@gmail.com>2019-05-28 20:14:05 +0200
committerDan Moseley <danmose@microsoft.com>2019-05-28 11:14:05 -0700
commite44730085c65ddb98dad1a3059b4e8f7a1ae33ea (patch)
tree8a759bc11ea5277f5b4de5734ea63285e07f978b /src/System.Private.CoreLib
parent89517b04ae89a39b4bde720f8cca87cfa4f12d2e (diff)
downloadcoreclr-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')
-rw-r--r--src/System.Private.CoreLib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs33
-rw-r--r--src/System.Private.CoreLib/shared/System/IO/Path.cs38
-rw-r--r--src/System.Private.CoreLib/shared/System/IO/PathInternal.cs18
-rw-r--r--src/System.Private.CoreLib/src/System/AppContext.CoreCLR.cs2
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;
}