7public static class Path
11 public unsafe readonly
char*
First;
19 public unsafe readonly
char*
Third;
25 public unsafe
Join3Payload(
char* first,
int firstLength,
char* second,
int secondLength,
char* third,
int thirdLength,
byte separators)
39 public unsafe readonly
char*
First;
47 public unsafe readonly
char*
Third;
57 public unsafe
Join4Payload(
char* first,
int firstLength,
char* second,
int secondLength,
char* third,
int thirdLength,
char* fourth,
int fourthLength,
byte separators)
79 [Obsolete(
"Path.InvalidPathChars has been deprecated. Use GetInvalidPathChars or GetInvalidFileNameChars instead.")]
84 [
return: NotNullIfNotNull(
"path")]
91 int num = path.Length;
96 for (
int num2 = path.Length - 1; num2 >= 0; num2--)
109 if (extension ==
null)
111 return path.Substring(0, num);
114 if (!extension.StartsWith(
'.'))
116 return string.Concat(readOnlySpan,
".", extension);
118 return string.Concat(readOnlySpan, extension);
128 if (directoryNameOffset < 0)
142 if (directoryNameOffset < 0)
146 return path.
Slice(0, directoryNameOffset);
153 if (num <= rootLength)
167 [
return: NotNullIfNotNull(
"path")]
180 for (
int num =
length - 1; num >= 0; num--)
199 [
return: NotNullIfNotNull(
"path")]
207 if (path.Length == fileName.
Length)
228 [
return: NotNullIfNotNull(
"path")]
236 if (path.Length == fileNameWithoutExtension.
Length)
240 return fileNameWithoutExtension.
ToString();
246 int num = fileName.LastIndexOf(
'.');
249 return fileName.
Slice(0, num);
256 byte* ptr = stackalloc
byte[8];
289 for (
int num = path.
Length - 1; num >= 0; num--)
294 return num != path.Length - 1;
304 public static string Combine(
string path1,
string path2)
306 if (path1 ==
null || path2 ==
null)
313 public static string Combine(
string path1,
string path2,
string path3)
315 if (path1 ==
null || path2 ==
null || path3 ==
null)
322 public static string Combine(
string path1,
string path2,
string path3,
string path4)
324 if (path1 ==
null || path2 ==
null || path3 ==
null || path4 ==
null)
326 throw new ArgumentNullException((path1 ==
null) ?
"path1" : ((path2 ==
null) ?
"path2" : ((path3 ==
null) ?
"path3" :
"path4")));
331 public static string Combine(params
string[] paths)
339 for (
int i = 0; i < paths.Length; i++)
341 if (paths[i] ==
null)
345 if (paths[i].Length != 0)
350 num = paths[i].Length;
354 num += paths[i].Length;
356 char c = paths[i][paths[i].Length - 1];
363 Span<char> initialBuffer = stackalloc
char[260];
366 for (
int j = num2; j < paths.Length; j++)
368 if (paths[j].Length == 0)
372 if (valueStringBuilder.
Length == 0)
374 valueStringBuilder.
Append(paths[j]);
377 char c2 = valueStringBuilder[valueStringBuilder.Length - 1];
380 valueStringBuilder.
Append(
'\\');
382 valueStringBuilder.
Append(paths[j]);
384 return valueStringBuilder.
ToString();
404 return Join(path2, path3);
408 return Join(path1, path3);
412 return Join(path1, path2);
421 return Join(path2, path3, path4);
425 return Join(path1, path3, path4);
429 return Join(path1, path2, path4);
433 return Join(path1, path2, path3);
438 public static string Join(
string? path1,
string? path2)
440 return Join(path1.AsSpan(), path2.AsSpan());
443 public static string Join(
string? path1,
string? path2,
string? path3)
445 return Join(path1.AsSpan(), path2.AsSpan(), path3.AsSpan());
448 public static string Join(
string? path1,
string? path2,
string? path3,
string? path4)
450 return Join(path1.AsSpan(), path2.AsSpan(), path3.AsSpan(), path4.AsSpan());
453 public static string Join(params
string?[] paths)
459 if (paths.Length == 0)
464 for (
int i = 0; i < paths.Length; i++)
466 num += paths[i]?.Length ?? 0;
468 num += paths.Length - 1;
469 Span<char> initialBuffer = stackalloc
char[260];
472 foreach (
string text in paths)
474 if (
string.IsNullOrEmpty(
text))
478 if (valueStringBuilder.Length == 0)
480 valueStringBuilder.Append(
text);
485 valueStringBuilder.Append(
'\\');
487 valueStringBuilder.Append(
text);
489 return valueStringBuilder.ToString();
507 charsWritten = reference.Length;
511 int num = path1.Length + path2.Length + (flag ? 1 : 0);
551 int num2 = path1.Length + path2.Length + path3.Length + num;
562 charsWritten += path3.
Length;
568 if (
string.IsNullOrEmpty(first))
572 if (
string.IsNullOrEmpty(second))
585 if (
string.IsNullOrEmpty(first))
589 if (
string.IsNullOrEmpty(second))
593 if (
string.IsNullOrEmpty(third))
605 return JoinInternal(first.AsSpan(), second.AsSpan(), third.AsSpan());
608 private static string CombineInternal(
string first,
string second,
string third,
string fourth)
610 if (
string.IsNullOrEmpty(first))
614 if (
string.IsNullOrEmpty(second))
618 if (
string.IsNullOrEmpty(third))
622 if (
string.IsNullOrEmpty(fourth))
638 return JoinInternal(first.AsSpan(), second.AsSpan(), third.AsSpan(), fourth.AsSpan());
645 return string.Concat(first,
"\\", second);
647 return string.Concat(first, second);
660 Join3Payload join3Payload =
new Join3Payload(first2, first.Length, second2, second.Length, third2, third.Length, (
byte)(b | (b2 << 1)));
665 if (((uint)reference.Separators & (
true ? 1u : 0u)) != 0)
669 new Span<char>(reference.Second, reference.SecondLength).
CopyTo(
destination.Slice(reference.FirstLength + (reference.Separators & 1)));
670 if ((reference.Separators & 2u) != 0)
672 destination[destination.Length - reference.ThirdLength - 1] =
'\\';
694 Join4Payload join4Payload =
new Join4Payload(first2, first.Length, second2, second.Length, third2, third.Length, fourth2, fourth.
Length, (
byte)(b | (b2 << 1) | (b3 << 2)));
699 int firstLength = reference.FirstLength;
700 if (((uint)reference.Separators & (
true ? 1u : 0u)) != 0)
705 firstLength += reference.SecondLength;
706 if ((reference.Separators & 2u) != 0)
711 firstLength += reference.ThirdLength;
712 if ((reference.Separators & 4u) != 0)
740 if ((b4 & 0x80u) != 0)
742 b3 = (byte)(b3 | 8u);
744 if ((b5 & 0x80u) != 0)
746 b3 = (byte)(b3 | 0x10u);
761 if (relativeTo ==
null)
788 int num2 = relativeTo.Length;
794 int num3 = path.Length;
799 if (num2 == num3 && num >= num2)
803 Span<char> initialBuffer = stackalloc
char[260];
808 valueStringBuilder.
Append(
"..");
809 for (
int i = num + 1; i < num2; i++)
814 valueStringBuilder.
Append(
"..");
822 int num4 = num3 - num;
829 if (valueStringBuilder.
Length > 0)
833 valueStringBuilder.
Append(path.AsSpan(num, num4));
835 return valueStringBuilder.
ToString();
862 '"',
'<',
'>',
'|',
'\0',
'\u0001',
'\u0002',
'\u0003',
'\u0004',
'\u0005',
863 '\u0006',
'\a',
'\b',
'\t',
'\n',
'\v',
'\f',
'\r',
'\u000e',
'\u000f',
864 '\u0010',
'\u0011',
'\u0012',
'\u0013',
'\u0014',
'\u0015',
'\u0016',
'\u0017',
'\u0018',
'\u0019',
865 '\u001a',
'\u001b',
'\u001c',
'\u001d',
'\u001e',
'\u001f',
':',
'*',
'?',
'\\',
874 '|',
'\0',
'\u0001',
'\u0002',
'\u0003',
'\u0004',
'\u0005',
'\u0006',
'\a',
'\b',
875 '\t',
'\n',
'\v',
'\f',
'\r',
'\u000e',
'\u000f',
'\u0010',
'\u0011',
'\u0012',
876 '\u0013',
'\u0014',
'\u0015',
'\u0016',
'\u0017',
'\u0018',
'\u0019',
'\u001a',
'\u001b',
'\u001c',
877 '\u001d',
'\u001e',
'\u001f'
891 if (path.Contains(
'\0'))
904 if (basePath ==
null)
912 if (basePath.Contains(
'\0') || path.Contains(
'\0'))
925 string text = ((
length >= 1 &&
PathInternal.
IsDirectorySeparator(path[0])) ?
Join(
GetPathRoot(basePath.AsSpan()), path.AsSpan(1)) : ((
length < 2 || !
PathInternal.
IsValidDriveChar(path[0]) || path[1] !=
':') ?
JoinInternal(basePath.AsSpan(), path.AsSpan()) : ((!
GetVolumeName(path.AsSpan()).EqualsOrdinal(
GetVolumeName(basePath.AsSpan()))) ? ((!
PathInternal.
IsDevice(basePath.AsSpan())) ? path.Insert(2,
"\\") : ((
length == 2) ?
JoinInternal(basePath.AsSpan(0, 4), path.AsSpan(),
"\\".AsSpan()) :
JoinInternal(basePath.AsSpan(0, 4), path.AsSpan(0, 2),
"\\".AsSpan(), path.AsSpan(2)))) :
Join(basePath.AsSpan(), path.AsSpan(2)))));
944 Span<char> initialBuffer = stackalloc
char[260];
957 builder.EnsureCapacity(checked((
int)tempPathW));
963 builder.Length = (int)tempPathW;
968 Span<char> initialBuffer = stackalloc
char[260];
971 initialBuffer = stackalloc
char[260];
975 if (tempFileNameW == 0)
979 path.Length = path.
RawChars.IndexOf(
'\0');
1001 return path[1] ==
':';
1015 if (path.Length == pathRoot.
Length)
1031 return path.
Slice(0, rootLength);
1039 if (pathRoot.
Length == 0)
1051 return readOnlySpan;
1053 return readOnlySpan.
Slice(0, readOnlySpan.
Length - 1);
1059 if (!flag && path.
Slice(0, 2).EqualsOrdinal(
"\\\\".AsSpan()))
1063 if (flag && path.
Length >= 8 && (path.
Slice(0, 8).EqualsOrdinal(
"\\\\?\\UNC\\".AsSpan()) || path.
Slice(5, 4).EqualsOrdinal(
"UNC\\".AsSpan())))
static uint GetTempPathW(int bufferLen, ref char buffer)
static uint GetTempFileNameW(ref char lpPathName, string lpPrefixString, uint uUnique, ref char lpTempFileName)
static unsafe void GetRandomBytes(byte *buffer, int length)
static string Normalize(string path)
static bool EndsInDirectorySeparator(string path)
static string RemoveRelativeSegments(string path, int rootLength)
static bool IsValidDriveChar(char value)
static int GetRootLength(ReadOnlySpan< char > path)
static string TrimEndingDirectorySeparator(string path)
static bool IsDirectorySeparator(char c)
static bool StartsWithDirectorySeparator(ReadOnlySpan< char > path)
static bool IsDevice(ReadOnlySpan< char > path)
static bool IsExtended(ReadOnlySpan< char > path)
static bool AreRootsEqual(string first, string second, StringComparison comparisonType)
static string NormalizeDirectorySeparators(string path)
static bool IsPartiallyQualified(ReadOnlySpan< char > path)
static bool IsEffectivelyEmpty(ReadOnlySpan< char > path)
static StringComparison StringComparison
static int GetCommonPathLength(string first, string second, bool ignoreCase)
static string Combine(string path1, string path2, string path3, string path4)
static ReadOnlySpan< char > TrimEndingDirectorySeparator(ReadOnlySpan< char > path)
static ? string GetFileNameWithoutExtension(string? path)
static ReadOnlySpan< char > GetDirectoryName(ReadOnlySpan< char > path)
static string Combine(string path1, string path2)
static ? string GetExtension(string? path)
static char[] GetInvalidFileNameChars()
static string CombineInternal(string first, string second, string third)
static ? string GetFileName(string? path)
static char[] GetInvalidPathChars()
static readonly char PathSeparator
static string GetFullPath(string path)
static string CombineInternal(string first, string second)
static string Combine(string path1, string path2, string path3)
static unsafe string JoinInternal(ReadOnlySpan< char > first, ReadOnlySpan< char > second, ReadOnlySpan< char > third)
static ReadOnlySpan< char > GetPathRoot(ReadOnlySpan< char > path)
static string Join(string? path1, string? path2, string? path3)
static string GetTempFileName()
static string Join(ReadOnlySpan< char > path1, ReadOnlySpan< char > path2, ReadOnlySpan< char > path3)
static bool IsPathRooted([NotNullWhen(true)] string? path)
static string Join(string? path1, string? path2, string? path3, string? path4)
static bool HasExtension([NotNullWhen(true)] string? path)
static bool EndsInDirectorySeparator(string path)
static bool IsPathRooted(ReadOnlySpan< char > path)
static string Join(ReadOnlySpan< char > path1, ReadOnlySpan< char > path2, ReadOnlySpan< char > path3, ReadOnlySpan< char > path4)
static bool HasExtension(ReadOnlySpan< char > path)
static string TrimEndingDirectorySeparator(string path)
static readonly char[] InvalidPathChars
static unsafe void Populate83FileNameFromRandomBytes(byte *bytes, int byteCount, Span< char > chars)
static string Combine(params string[] paths)
static string GetTempPath()
static string Join(ReadOnlySpan< char > path1, ReadOnlySpan< char > path2)
static ? string GetPathRoot(string? path)
static void GetTempPath(ref ValueStringBuilder builder)
static int GetUncRootLength(ReadOnlySpan< char > path)
static readonly char AltDirectorySeparatorChar
static readonly char DirectorySeparatorChar
static bool IsPathFullyQualified(string path)
static readonly char VolumeSeparatorChar
static ReadOnlySpan< char > GetFileName(ReadOnlySpan< char > path)
static bool IsPathFullyQualified(ReadOnlySpan< char > path)
static string GetRelativePath(string relativeTo, string path, StringComparison comparisonType)
static unsafe string GetRandomFileName()
static bool TryJoin(ReadOnlySpan< char > path1, ReadOnlySpan< char > path2, Span< char > destination, out int charsWritten)
static string GetFullPathInternal(string path)
static string CombineInternal(string first, string second, string third, string fourth)
static string Join(string? path1, string? path2)
static bool TryJoin(ReadOnlySpan< char > path1, ReadOnlySpan< char > path2, ReadOnlySpan< char > path3, Span< char > destination, out int charsWritten)
static bool EndsInDirectorySeparator(ReadOnlySpan< char > path)
static int GetDirectoryNameOffset(ReadOnlySpan< char > path)
static string GetFullPath(string path, string basePath)
static ReadOnlySpan< char > GetVolumeName(ReadOnlySpan< char > path)
static ReadOnlySpan< char > GetFileNameWithoutExtension(ReadOnlySpan< char > path)
static string Join(params string?[] paths)
static ? string GetDirectoryName(string? path)
static ReadOnlySpan< char > GetExtension(ReadOnlySpan< char > path)
static string GetRelativePath(string relativeTo, string path)
static string JoinInternal(ReadOnlySpan< char > first, ReadOnlySpan< char > second)
static unsafe string JoinInternal(ReadOnlySpan< char > first, ReadOnlySpan< char > second, ReadOnlySpan< char > third, ReadOnlySpan< char > fourth)
static ReadOnlySpan< byte > Base32Char
static ? string ChangeExtension(string? path, string? extension)
static Exception GetExceptionForLastWin32Error(string path="")
static byte Max(byte val1, byte val2)
static string Argument_InvalidPathChars
static string Arg_PathEmpty
static string Arg_BasePathNotFullyQualified
unsafe readonly char * Second
unsafe readonly char * First
readonly int SecondLength
unsafe Join3Payload(char *first, int firstLength, char *second, int secondLength, char *third, int thirdLength, byte separators)
unsafe readonly char * Third
unsafe readonly char * First
unsafe readonly char * Second
readonly int FourthLength
readonly int SecondLength
unsafe readonly char * Third
unsafe readonly char * Fourth
unsafe Join4Payload(char *first, int firstLength, char *second, int secondLength, char *third, int thirdLength, char *fourth, int fourthLength, byte separators)
void CopyTo(Span< T > destination)
static ReadOnlySpan< T > Empty
ReadOnlySpan< T > Slice(int start)
override string ToString()
void CopyTo(Span< T > destination)
ref char GetPinnableReference()
void EnsureCapacity(int capacity)
override string ToString()