summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlake Hensley <jbhensley@users.noreply.github.com>2019-05-01 21:07:07 -0700
committerAnirudh Agnihotry <anirudhagnihotry098@gmail.com>2019-05-01 21:07:07 -0700
commit886b81692e13861cd1aa80e72e726792093ca671 (patch)
treec7eaeb867c2a1b03423a114f5356ed9561cff4f8
parent78360d92a412b3ba8f0577121fcbb488a11e797f (diff)
downloadcoreclr-886b81692e13861cd1aa80e72e726792093ca671.tar.gz
coreclr-886b81692e13861cd1aa80e72e726792093ca671.tar.bz2
coreclr-886b81692e13861cd1aa80e72e726792093ca671.zip
Added overloads to Path.Join (#24307)
* Added overloads to Path.Join * Refactor Path.Join and Path.Combine to use ValueStringBuilder * Use proper defined const for empty string * Fix Windows-specific const
-rw-r--r--src/System.Private.CoreLib/shared/System/IO/Path.cs96
1 files changed, 85 insertions, 11 deletions
diff --git a/src/System.Private.CoreLib/shared/System/IO/Path.cs b/src/System.Private.CoreLib/shared/System/IO/Path.cs
index db491bfdc0..27741b9248 100644
--- a/src/System.Private.CoreLib/shared/System/IO/Path.cs
+++ b/src/System.Private.CoreLib/shared/System/IO/Path.cs
@@ -346,7 +346,7 @@ namespace System.IO
throw new ArgumentNullException(nameof(paths));
}
- int finalSize = 0;
+ int maxSize = 0;
int firstComponent = 0;
// We have two passes, the first calculates how large a buffer to allocate and does some precondition
@@ -367,19 +367,21 @@ namespace System.IO
if (IsPathRooted(paths[i]))
{
firstComponent = i;
- finalSize = paths[i].Length;
+ maxSize = paths[i].Length;
}
else
{
- finalSize += paths[i].Length;
+ maxSize += paths[i].Length;
}
char ch = paths[i][paths[i].Length - 1];
if (!PathInternal.IsDirectorySeparator(ch))
- finalSize++;
+ maxSize++;
}
- StringBuilder finalPath = StringBuilderCache.Acquire(finalSize);
+ Span<char> initialBuffer = stackalloc char[260]; // MaxShortPath on Windows
+ var builder = new ValueStringBuilder(initialBuffer);
+ builder.EnsureCapacity(maxSize);
for (int i = firstComponent; i < paths.Length; i++)
{
@@ -388,23 +390,23 @@ namespace System.IO
continue;
}
- if (finalPath.Length == 0)
+ if (builder.Length == 0)
{
- finalPath.Append(paths[i]);
+ builder.Append(paths[i]);
}
else
{
- char ch = finalPath[finalPath.Length - 1];
+ char ch = builder[builder.Length - 1];
if (!PathInternal.IsDirectorySeparator(ch))
{
- finalPath.Append(PathInternal.DirectorySeparatorChar);
+ builder.Append(PathInternal.DirectorySeparatorChar);
}
- finalPath.Append(paths[i]);
+ builder.Append(paths[i]);
}
}
- return StringBuilderCache.GetStringAndRelease(finalPath);
+ return builder.ToString();
}
// Unlike Combine(), Join() methods do not consider rooting. They simply combine paths, ensuring that there
@@ -434,6 +436,23 @@ namespace System.IO
return JoinInternal(path1, path2, path3);
}
+ public static string Join(ReadOnlySpan<char> path1, ReadOnlySpan<char> path2, ReadOnlySpan<char> path3, ReadOnlySpan<char> path4)
+ {
+ if (path1.Length == 0)
+ return Join(path2, path3, path4);
+
+ if (path2.Length == 0)
+ return Join(path1, path3, path4);
+
+ if (path3.Length == 0)
+ return Join(path1, path2, path4);
+
+ if (path4.Length == 0)
+ return Join(path1, path2, path3);
+
+ return JoinInternal(path1, path2, path3, path4);
+ }
+
public static string Join(string? path1, string? path2)
{
return Join(path1.AsSpan(), path2.AsSpan());
@@ -444,6 +463,61 @@ namespace System.IO
return Join(path1.AsSpan(), path2.AsSpan(), path3.AsSpan());
}
+ public static string Join(string? path1, string? path2, string? path3, string? path4)
+ {
+ return Join(path1.AsSpan(), path2.AsSpan(), path3.AsSpan(), path4.AsSpan());
+ }
+
+ public static string Join(params string[] paths)
+ {
+ if (paths == null)
+ {
+ throw new ArgumentNullException(nameof(paths));
+ }
+
+ if (paths.Length == 0)
+ {
+ return string.Empty;
+ }
+
+ int maxSize = 0;
+ foreach (string path in paths)
+ {
+ maxSize += path?.Length ?? 0;
+ }
+ maxSize += paths.Length - 1;
+
+ Span<char> initialBuffer = stackalloc char[260]; // MaxShortPath on Windows
+ var builder = new ValueStringBuilder(initialBuffer);
+ builder.EnsureCapacity(maxSize);
+
+ for (int i = 0; i < paths.Length; i++)
+ {
+ if ((paths[i]?.Length ?? 0) == 0)
+ {
+ continue;
+ }
+
+ string path = paths[i];
+
+ if (builder.Length == 0)
+ {
+ builder.Append(path);
+ }
+ else
+ {
+ if (!PathInternal.IsDirectorySeparator(builder[builder.Length - 1]) && !PathInternal.IsDirectorySeparator(path[0]))
+ {
+ builder.Append(PathInternal.DirectorySeparatorChar);
+ }
+
+ builder.Append(path);
+ }
+ }
+
+ return builder.ToString();
+ }
+
public static bool TryJoin(ReadOnlySpan<char> path1, ReadOnlySpan<char> path2, Span<char> destination, out int charsWritten)
{
charsWritten = 0;