Imported Upstream version 6.4.0.137

Former-commit-id: 943baa9f16a098c33e129777827f3a9d20da00d6
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2019-07-26 19:53:28 +00:00
parent e9207cf623
commit ef583813eb
2712 changed files with 74169 additions and 40587 deletions

View File

@ -55,11 +55,11 @@ namespace System.IO {
}
DriveInfo [] drives = GetDrives ();
Array.Sort (drives, (DriveInfo di1, DriveInfo di2) => String.Compare (di2.path, di1.path, true));
foreach (DriveInfo d in drives){
if (d.path == driveName){
if (driveName.StartsWith (d.path, StringComparison.OrdinalIgnoreCase)){
this.path = d.path;
this.drive_format = d.drive_format;
this.path = d.path;
return;
}
}

View File

@ -343,7 +343,7 @@ namespace System.IO
}
}
public string Name {
public virtual string Name {
get {
return name;
}

View File

@ -51,7 +51,7 @@ using System.Diagnostics;
namespace System.IO {
[ComVisible (true)]
public static class Path {
public static partial class Path {
[Obsolete ("see GetInvalidPathChars and GetInvalidFileNameChars methods.")]
public static readonly char[] InvalidPathChars;
@ -278,7 +278,6 @@ namespace System.IO {
return path;
}
public static string GetFileNameWithoutExtension (string path)
{
return ChangeExtension (GetFileName (path), null);
@ -434,7 +433,6 @@ namespace System.IO {
internal static bool IsDirectorySeparator (char c) {
return c == DirectorySeparatorChar || c == AltDirectorySeparatorChar;
}
public static string GetPathRoot (string path)
{
if (path == null)
@ -569,6 +567,7 @@ namespace System.IO {
public static char[] GetInvalidFileNameChars ()
{
#pragma warning disable 162
// return a new array as we do not want anyone to be able to change the values
if (Environment.IsRunningOnWindows) {
return new char [41] { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
@ -578,10 +577,12 @@ namespace System.IO {
} else {
return new char [2] { '\x00', '/' };
}
#pragma warning restore 162
}
public static char[] GetInvalidPathChars ()
{
#pragma warning disable 162
// return a new array as we do not want anyone to be able to change the values
if (Environment.IsRunningOnWindows) {
return new char [36] { '\x22', '\x3C', '\x3E', '\x7C', '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
@ -591,6 +592,7 @@ namespace System.IO {
} else {
return new char [1] { '\x00' };
}
#pragma warning restore 162
}
public static string GetRandomFileName ()
@ -699,6 +701,7 @@ namespace System.IO {
static string CanonicalizePath (string path)
{
#pragma warning disable 162
// STEP 1: Check for empty string
if (path == null)
return path;
@ -780,6 +783,7 @@ namespace System.IO {
}
return ret;
}
#pragma warning restore 162
}
// required for FileIOPermission (and most proibably reusable elsewhere too)

View File

@ -0,0 +1,185 @@
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Diagnostics;
namespace System.IO
{
partial class Path
{
public static ReadOnlySpan<char> GetExtension (ReadOnlySpan<char> path) => GetExtension (path.ToString ()).AsSpan ();
public static ReadOnlySpan<char> GetFileNameWithoutExtension (ReadOnlySpan<char> path) => GetFileNameWithoutExtension (path.ToString ()).AsSpan ();
public static ReadOnlySpan<char> GetPathRoot (ReadOnlySpan<char> path) => GetPathRoot (path.ToString ()).AsSpan ();
public static bool HasExtension (ReadOnlySpan<char> path) => HasExtension (path.ToString ());
public static string GetRelativePath(string relativeTo, string path)
{
return GetRelativePath(relativeTo, path, StringComparison);
}
private static string GetRelativePath(string relativeTo, string path, StringComparison comparisonType)
{
if (string.IsNullOrEmpty(relativeTo)) throw new ArgumentNullException(nameof(relativeTo));
if (PathInternal.IsEffectivelyEmpty(path.AsSpan())) throw new ArgumentNullException(nameof(path));
Debug.Assert(comparisonType == StringComparison.Ordinal || comparisonType == StringComparison.OrdinalIgnoreCase);
relativeTo = GetFullPath(relativeTo);
path = GetFullPath(path);
// Need to check if the roots are different- if they are we need to return the "to" path.
if (!PathInternal.AreRootsEqual(relativeTo, path, comparisonType))
return path;
int commonLength = PathInternal.GetCommonPathLength(relativeTo, path, ignoreCase: comparisonType == StringComparison.OrdinalIgnoreCase);
// If there is nothing in common they can't share the same root, return the "to" path as is.
if (commonLength == 0)
return path;
// Trailing separators aren't significant for comparison
int relativeToLength = relativeTo.Length;
if (PathInternal.EndsInDirectorySeparator(relativeTo.AsSpan()))
relativeToLength--;
bool pathEndsInSeparator = PathInternal.EndsInDirectorySeparator(path.AsSpan());
int pathLength = path.Length;
if (pathEndsInSeparator)
pathLength--;
// If we have effectively the same path, return "."
if (relativeToLength == pathLength && commonLength >= relativeToLength) return ".";
// We have the same root, we need to calculate the difference now using the
// common Length and Segment count past the length.
//
// Some examples:
//
// C:\Foo C:\Bar L3, S1 -> ..\Bar
// C:\Foo C:\Foo\Bar L6, S0 -> Bar
// C:\Foo\Bar C:\Bar\Bar L3, S2 -> ..\..\Bar\Bar
// C:\Foo\Foo C:\Foo\Bar L7, S1 -> ..\Bar
StringBuilder sb = StringBuilderCache.Acquire(Math.Max(relativeTo.Length, path.Length));
// Add parent segments for segments past the common on the "from" path
if (commonLength < relativeToLength)
{
sb.Append("..");
for (int i = commonLength + 1; i < relativeToLength; i++)
{
if (PathInternal.IsDirectorySeparator(relativeTo[i]))
{
sb.Append(DirectorySeparatorChar);
sb.Append("..");
}
}
}
else if (PathInternal.IsDirectorySeparator(path[commonLength]))
{
// No parent segments and we need to eat the initial separator
// (C:\Foo C:\Foo\Bar case)
commonLength++;
}
// Now add the rest of the "to" path, adding back the trailing separator
int differenceLength = pathLength - commonLength;
if (pathEndsInSeparator)
differenceLength++;
if (differenceLength > 0)
{
if (sb.Length > 0)
{
sb.Append(DirectorySeparatorChar);
}
sb.Append(path, commonLength, differenceLength);
}
return StringBuilderCache.GetStringAndRelease(sb);
}
/// <summary>Returns a comparison that can be used to compare file and directory names for equality.</summary>
internal static StringComparison StringComparison
{
get
{
return IsCaseSensitive ?
StringComparison.Ordinal :
StringComparison.OrdinalIgnoreCase;
}
}
internal static bool IsCaseSensitive => !IsWindows;
static bool IsWindows
{
get
{
PlatformID platform = Environment.OSVersion.Platform;
if (platform == PlatformID.Win32S ||
platform == PlatformID.Win32Windows ||
platform == PlatformID.Win32NT ||
platform == PlatformID.WinCE) {
return true;
}
return false;
}
}
public static bool IsPathFullyQualified(string path)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
return IsPathFullyQualified(path.AsSpan());
}
public static bool IsPathFullyQualified(ReadOnlySpan<char> path)
{
return !PathInternal.IsPartiallyQualified(path);
}
public static string GetFullPath(string path, string basePath)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
if (basePath == null)
throw new ArgumentNullException(nameof(basePath));
if (!IsPathFullyQualified(basePath))
throw new ArgumentException(SR.Arg_BasePathNotFullyQualified, nameof(basePath));
if (basePath.Contains('\0') || path.Contains('\0'))
throw new ArgumentException(SR.Argument_InvalidPathChars);
if (IsPathFullyQualified(path))
return GetFullPath(path);
return GetFullPath(CombineInternal(basePath, path));
}
private static string CombineInternal(string first, string second)
{
if (string.IsNullOrEmpty(first))
return second;
if (string.IsNullOrEmpty(second))
return first;
if (IsPathRooted(second.AsSpan()))
return second;
return JoinInternal(first.AsSpan(), second.AsSpan());
}
}
}