summaryrefslogtreecommitdiff
path: root/src/mscorlib/corefx/System
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/corefx/System')
-rw-r--r--src/mscorlib/corefx/System/Buffers/ArrayPool.cs25
-rw-r--r--src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs2
-rw-r--r--src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Unix.cs28
-rw-r--r--src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Windows.cs20
-rw-r--r--src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs46
-rw-r--r--src/mscorlib/corefx/System/Globalization/Calendar.cs9
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs7
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs1
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs8
-rw-r--r--src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs32
-rw-r--r--src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs10
-rw-r--r--src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs4
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs7
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs3
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs11
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureTypes.cs4
-rw-r--r--src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs8
-rw-r--r--src/mscorlib/corefx/System/Globalization/DigitShapes.cs1
-rw-r--r--src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs1
-rw-r--r--src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs5
-rw-r--r--src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs1
-rw-r--r--src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs36
-rw-r--r--src/mscorlib/corefx/System/Globalization/HijriCalendar.cs5
-rw-r--r--src/mscorlib/corefx/System/Globalization/IdnMapping.Windows.cs2
-rw-r--r--src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs22
-rw-r--r--src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs6
-rw-r--r--src/mscorlib/corefx/System/Globalization/JapaneseLunisolarCalendar.cs6
-rw-r--r--src/mscorlib/corefx/System/Globalization/JulianCalendar.cs5
-rw-r--r--src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs6
-rw-r--r--src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs6
-rw-r--r--src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs54
-rw-r--r--src/mscorlib/corefx/System/Globalization/RegionInfo.cs2
-rw-r--r--src/mscorlib/corefx/System/Globalization/SortKey.cs1
-rw-r--r--src/mscorlib/corefx/System/Globalization/SortVersion.cs50
-rw-r--r--src/mscorlib/corefx/System/Globalization/StringInfo.cs3
-rw-r--r--src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs6
-rw-r--r--src/mscorlib/corefx/System/Globalization/TaiwanLunisolarCalendar.cs6
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs1
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs2
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextInfo.cs3
-rw-r--r--src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs6
-rw-r--r--src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs2
-rw-r--r--src/mscorlib/corefx/System/IO/FileStream.NetStandard17.cs76
-rw-r--r--src/mscorlib/corefx/System/IO/FileStream.Win32.cs76
-rw-r--r--src/mscorlib/corefx/System/IO/FileStream.cs94
-rw-r--r--src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs6
-rw-r--r--src/mscorlib/corefx/System/IO/Path.Unix.cs62
-rw-r--r--src/mscorlib/corefx/System/IO/Path.Windows.cs32
-rw-r--r--src/mscorlib/corefx/System/IO/Path.cs33
-rw-r--r--src/mscorlib/corefx/System/IO/PathHelper.Windows.cs245
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs75
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.Unix.cs42
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs18
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.Windows.cs124
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.cs58
-rw-r--r--src/mscorlib/corefx/System/IO/Win32Marshal.cs45
-rw-r--r--src/mscorlib/corefx/System/Runtime/InteropServices/NativeBuffer.cs157
-rw-r--r--src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandle.cs109
-rw-r--r--src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs97
-rw-r--r--src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs199
-rw-r--r--src/mscorlib/corefx/System/Security/SecureString.Windows.cs8
61 files changed, 568 insertions, 1451 deletions
diff --git a/src/mscorlib/corefx/System/Buffers/ArrayPool.cs b/src/mscorlib/corefx/System/Buffers/ArrayPool.cs
index 441e48dab4..77a07f7fa5 100644
--- a/src/mscorlib/corefx/System/Buffers/ArrayPool.cs
+++ b/src/mscorlib/corefx/System/Buffers/ArrayPool.cs
@@ -29,26 +29,13 @@ namespace System.Buffers
/// array than was requested. Renting a buffer from it with <see cref="Rent"/> will result in an
/// existing buffer being taken from the pool if an appropriate buffer is available or in a new
/// buffer being allocated if one is not available.
+ /// byte[] and char[] are the most commonly pooled array types. For these we use a special pool type
+ /// optimized for very fast access speeds, at the expense of more memory consumption.
+ /// The shared pool instance is created lazily on first access.
/// </remarks>
- public static ArrayPool<T> Shared => SharedPool.Value;
-
- /// <summary>Stores a cached pool instance for T[].</summary>
- /// <remarks>
- /// Separated out into a nested class to enable lazy-initialization of the pool provided by
- /// the runtime, only forced when Shared is used (and not when Create is called or when
- /// other non-Shared accesses happen).
- /// </remarks>
- private static class SharedPool
- {
- /// <summary>Per-type cached pool.</summary>
- /// <remarks>
- /// byte[] and char[] are the most commonly pooled array types. For these we use a special pool type
- /// optimized for very fast access speeds, at the expense of more memory consumption.
- /// </remarks>
- internal readonly static ArrayPool<T> Value =
- typeof(T) == typeof(byte) || typeof(T) == typeof(char) ? new TlsOverPerCoreLockedStacksArrayPool<T>() :
- Create();
- }
+ public static ArrayPool<T> Shared { get; } =
+ typeof(T) == typeof(byte) || typeof(T) == typeof(char) ? new TlsOverPerCoreLockedStacksArrayPool<T>() :
+ Create();
/// <summary>
/// Creates a new <see cref="ArrayPool{T}"/> instance using default configuration options.
diff --git a/src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs b/src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs
index 1e0e769530..f7b6034d20 100644
--- a/src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs
+++ b/src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs
@@ -70,7 +70,7 @@ namespace System.Buffers
{
// No need for events with the empty array. Our pool is effectively infinite
// and we'll never allocate for rents and never store for returns.
- return EmptyArray<T>.Value;
+ return Array.Empty<T>();
}
var log = ArrayPoolEventSource.Log;
diff --git a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Unix.cs b/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Unix.cs
deleted file mode 100644
index 8a1d006b12..0000000000
--- a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Unix.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using Microsoft.Win32;
-using System.Runtime.CompilerServices;
-
-namespace System.Buffers
-{
- internal sealed partial class TlsOverPerCoreLockedStacksArrayPool<T>
- {
- /// <summary>Get an identifier for the current thread to use to index into the stacks.</summary>
- private static int ExecutionId
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
- {
- // On Unix, CurrentProcessorNumber is implemented in terms of sched_getcpu, which
- // doesn't exist on all platforms. On those it doesn't exist on, GetCurrentProcessorNumber
- // returns -1. As a fallback in that case and to spread the threads across the buckets
- // by default, we use the current managed thread ID as a proxy.
- int id = CurrentProcessorNumber;
- if (id < 0) id = Environment.CurrentManagedThreadId;
- return id;
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Windows.cs b/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Windows.cs
deleted file mode 100644
index d42242c910..0000000000
--- a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Windows.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using Microsoft.Win32;
-using System.Runtime.CompilerServices;
-using System.Threading;
-
-namespace System.Buffers
-{
- internal sealed partial class TlsOverPerCoreLockedStacksArrayPool<T> : ArrayPool<T>
- {
- /// <summary>Get an identifier for the current thread to use to index into the stacks.</summary>
- private static int ExecutionId
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get { return CurrentProcessorNumber; }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs b/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs
index debc33615f..64c5cebe85 100644
--- a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs
+++ b/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs
@@ -45,11 +45,6 @@ namespace System.Buffers
/// <summary>A per-thread array of arrays, to cache one array per array size per thread.</summary>
[ThreadStatic]
private static T[][] t_tlsBuckets;
- /// <summary>
- /// Cached processor number used as a hint for which per-core stack to access.
- /// </summary>
- [ThreadStatic]
- private static int? t_cachedProcessorNumber;
/// <summary>Initialize the pool.</summary>
public TlsOverPerCoreLockedStacksArrayPool()
@@ -72,22 +67,6 @@ namespace System.Buffers
/// <summary>Gets an ID for the pool to use with events.</summary>
private int Id => GetHashCode();
- /// <summary>Gets the processor number associated with the current thread.</summary>
- /// <remarks>Uses a cached value if one exists on the current thread.</remarks>
- private static int CurrentProcessorNumber
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
- {
- int? num = t_cachedProcessorNumber;
- if (!num.HasValue)
- {
- t_cachedProcessorNumber = num = Environment.CurrentProcessorNumber;
- }
- return num.GetValueOrDefault();
- }
- }
-
public override T[] Rent(int minimumLength)
{
// Arrays can't be smaller than zero. We allow requesting zero-length arrays (even though
@@ -101,7 +80,7 @@ namespace System.Buffers
{
// No need to log the empty array. Our pool is effectively infinite
// and we'll never allocate for rents and never store for returns.
- return EmptyArray<T>.Value;
+ return Array.Empty<T>();
}
ArrayPoolEventSource log = ArrayPoolEventSource.Log;
@@ -249,7 +228,7 @@ namespace System.Buffers
// Try to push on to the associated stack first. If that fails,
// round-robin through the other stacks.
LockedStack[] stacks = _perCoreStacks;
- int index = ExecutionId % stacks.Length;
+ int index = Environment.CurrentExecutionId % stacks.Length;
for (int i = 0; i < stacks.Length; i++)
{
if (stacks[index].TryPush(array)) return;
@@ -265,7 +244,7 @@ namespace System.Buffers
// round-robin through the other stacks.
T[] arr;
LockedStack[] stacks = _perCoreStacks;
- int index = ExecutionId % stacks.Length;
+ int index = Environment.CurrentExecutionId % stacks.Length;
for (int i = 0; i < stacks.Length; i++)
{
if ((arr = stacks[index].TryPop()) != null) return arr;
@@ -285,7 +264,7 @@ namespace System.Buffers
public bool TryPush(T[] array)
{
bool enqueued = false;
- MonitorEnterWithProcNumberFlush(this);
+ Monitor.Enter(this);
if (_count < MaxBuffersPerArraySizePerCore)
{
_arrays[_count++] = array;
@@ -299,7 +278,7 @@ namespace System.Buffers
public T[] TryPop()
{
T[] arr = null;
- MonitorEnterWithProcNumberFlush(this);
+ Monitor.Enter(this);
if (_count > 0)
{
arr = _arrays[--_count];
@@ -308,21 +287,6 @@ namespace System.Buffers
Monitor.Exit(this);
return arr;
}
-
- /// <summary>
- /// Enters the monitor on the object. If there is any contention while trying
- /// to acquire the monitor, it flushes the cached processor number so that subsequent
- /// attempts to access the per-core stacks will use an updated processor number.
- /// </summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void MonitorEnterWithProcNumberFlush(object obj)
- {
- if (!Monitor.TryEnter(obj))
- {
- t_cachedProcessorNumber = null;
- Monitor.Enter(obj);
- }
- }
}
}
}
diff --git a/src/mscorlib/corefx/System/Globalization/Calendar.cs b/src/mscorlib/corefx/System/Globalization/Calendar.cs
index 78e9f00d08..0ff5040c74 100644
--- a/src/mscorlib/corefx/System/Globalization/Calendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/Calendar.cs
@@ -29,7 +29,6 @@ namespace System.Globalization
// since most of the calendars (or all?) have the same way of calcuating hour/minute/second.
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public abstract partial class Calendar : ICloneable
{
// Number of 100ns (10E-7 second) ticks per time unit
@@ -77,7 +76,6 @@ namespace System.Globalization
// The minimum supported DateTime range for the calendar.
- [System.Runtime.InteropServices.ComVisible(false)]
public virtual DateTime MinSupportedDateTime
{
get
@@ -88,7 +86,6 @@ namespace System.Globalization
// The maximum supported DateTime range for the calendar.
- [System.Runtime.InteropServices.ComVisible(false)]
public virtual DateTime MaxSupportedDateTime
{
get
@@ -97,7 +94,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public virtual CalendarAlgorithmType AlgorithmType
{
get
@@ -138,7 +134,6 @@ namespace System.Globalization
// Detect if the object is readonly.
//
////////////////////////////////////////////////////////////////////////
- [System.Runtime.InteropServices.ComVisible(false)]
public bool IsReadOnly
{
get { return (_isReadOnly); }
@@ -151,7 +146,6 @@ namespace System.Globalization
// Is the implementation of ICloneable.
//
////////////////////////////////////////////////////////////////////////
- [System.Runtime.InteropServices.ComVisible(false)]
public virtual object Clone()
{
object o = MemberwiseClone();
@@ -167,7 +161,6 @@ namespace System.Globalization
// readonly.
//
////////////////////////////////////////////////////////////////////////
- [System.Runtime.InteropServices.ComVisible(false)]
public static Calendar ReadOnly(Calendar calendar)
{
if (calendar == null) { throw new ArgumentNullException(nameof(calendar)); }
@@ -708,7 +701,6 @@ namespace System.Globalization
// if this calendar does not have leap month, or this year is not a leap year.
//
- [System.Runtime.InteropServices.ComVisible(false)]
public virtual int GetLeapMonth(int year)
{
return (GetLeapMonth(year, CurrentEra));
@@ -718,7 +710,6 @@ namespace System.Globalization
// if this calendar does not have leap month, or this year is not a leap year.
//
- [System.Runtime.InteropServices.ComVisible(false)]
public virtual int GetLeapMonth(int year, int era)
{
if (!IsLeapYear(year, era))
diff --git a/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs b/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs
index 270d62f143..19c81f17b0 100644
--- a/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs
+++ b/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs
@@ -64,7 +64,6 @@ namespace System.Globalization
}
// Call native side to figure out which calendars are allowed
- [SecuritySafeCritical]
internal static int GetCalendars(string localeName, bool useUserOverride, CalendarId[] calendars)
{
// NOTE: there are no 'user overrides' on Linux
@@ -87,7 +86,6 @@ namespace System.Globalization
// PAL Layer ends here
- [SecuritySafeCritical]
private static bool GetCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string calendarString)
{
return Interop.CallStringMethod(
@@ -239,7 +237,6 @@ namespace System.Globalization
return index - startIndex;
}
- [SecuritySafeCritical]
private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] monthNames)
{
monthNames = null;
@@ -261,7 +258,6 @@ namespace System.Globalization
return result;
}
- [SecuritySafeCritical]
private static bool EnumEraNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] eraNames)
{
bool result = EnumCalendarInfo(localeName, calendarId, dataType, out eraNames);
@@ -277,7 +273,6 @@ namespace System.Globalization
return result;
}
- [SecuritySafeCritical]
internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] calendarData)
{
calendarData = null;
@@ -292,7 +287,6 @@ namespace System.Globalization
return result;
}
- [SecuritySafeCritical]
private static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, CallbackContext callbackContext)
{
GCHandle context = GCHandle.Alloc(callbackContext);
@@ -306,7 +300,6 @@ namespace System.Globalization
}
}
- [SecuritySafeCritical]
private static void EnumCalendarInfoCallback(string calendarString, IntPtr context)
{
CallbackContext callbackContext = (CallbackContext)((GCHandle)context).Target;
diff --git a/src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs b/src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs
index 490951e1f0..4013ce7237 100644
--- a/src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs
+++ b/src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs
@@ -7,7 +7,6 @@ using System;
namespace System.Globalization
{
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public enum CalendarWeekRule
{
FirstDay = 0, // Week 1 begins on the first day of the year
diff --git a/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs b/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs
index 149e63c689..7de75d6aee 100644
--- a/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs
+++ b/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs
@@ -22,8 +22,8 @@ namespace System.Globalization
private const int SecondsPerMinute = 60;
private const int MinutesPerDegree = 60;
- private static readonly long StartOf1810 = GetNumberOfDays(new DateTime(1810, 1, 1));
- private static readonly long StartOf1900Century = GetNumberOfDays(new DateTime(1900, 1, 1));
+ private static readonly long s_startOf1810 = GetNumberOfDays(new DateTime(1810, 1, 1));
+ private static readonly long s_startOf1900Century = GetNumberOfDays(new DateTime(1900, 1, 1));
private static readonly double[] s_coefficients1900to1987 = new double[] { -0.00002, 0.000297, 0.025184, -0.181133, 0.553040, -0.861938, 0.677066, -0.212591 };
private static readonly double[] s_coefficients1800to1899 = new double[] { -0.000009, 0.003844, 0.083563, 0.865736, 4.867575, 15.845535, 31.332267, 38.291999, 28.316289, 11.636204, 2.043794 };
@@ -146,7 +146,7 @@ namespace System.Globalization
private static double CenturiesFrom1900(int gregorianYear)
{
long july1stOfYear = GetNumberOfDays(new DateTime(gregorianYear, 7, 1));
- return (double)(july1stOfYear - StartOf1900Century) / DaysInUniformLengthCentury;
+ return (double)(july1stOfYear - s_startOf1900Century) / DaysInUniformLengthCentury;
}
// the following formulas defines a polynomial function which gives us the amount that the earth is slowing down for specific year ranges
@@ -154,7 +154,7 @@ namespace System.Globalization
{
Debug.Assert(gregorianYear < 1620 || 2020 <= gregorianYear);
long january1stOfYear = GetNumberOfDays(new DateTime(gregorianYear, 1, 1));
- double daysSinceStartOf1810 = january1stOfYear - StartOf1810;
+ double daysSinceStartOf1810 = january1stOfYear - s_startOf1810;
double x = TwelveHours + daysSinceStartOf1810;
return ((Math.Pow(x, 2) / 41048480) - 15) / SecondsPerDay;
}
diff --git a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs
index dc38ca405b..38ce441a78 100644
--- a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs
@@ -194,7 +194,7 @@ namespace System.Globalization
// Get the level 2 WORD offset from the 4 - 7 bit of ch. This provides the base offset of the level 3 table.
// Note that & has the lower precedence than addition, so don't forget the parathesis.
index = s_pNumericLevel1Index[index + ((ch >> 4) & 0x000f)];
-
+
fixed (ushort* pUshortPtr = &(s_pNumericLevel1Index[index]))
{
byte* pBytePtr = (byte*)pUshortPtr;
@@ -238,46 +238,46 @@ namespace System.Globalization
return (InternalGetNumericValue(InternalConvertToUtf32(s, index)));
}
- public static int GetDecimalDigitValue(char ch)
+ public static int GetDecimalDigitValue(char ch)
{
- return (sbyte) (InternalGetDigitValues(ch) >> 8);
+ return (sbyte)(InternalGetDigitValues(ch) >> 8);
}
- public static int GetDecimalDigitValue(String s, int index)
+ public static int GetDecimalDigitValue(String s, int index)
{
- if (s == null)
+ if (s == null)
{
throw new ArgumentNullException(nameof(s));
}
-
- if (index < 0 || index >= s.Length)
+
+ if (index < 0 || index >= s.Length)
{
throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
}
Contract.EndContractBlock();
- return (sbyte) (InternalGetDigitValues(InternalConvertToUtf32(s, index)) >> 8);
+ return (sbyte)(InternalGetDigitValues(InternalConvertToUtf32(s, index)) >> 8);
}
-
+
public static int GetDigitValue(char ch)
{
- return (sbyte) (InternalGetDigitValues(ch) & 0x00FF);
+ return (sbyte)(InternalGetDigitValues(ch) & 0x00FF);
}
- public static int GetDigitValue(String s, int index)
+ public static int GetDigitValue(String s, int index)
{
- if (s == null)
+ if (s == null)
{
throw new ArgumentNullException(nameof(s));
}
-
- if (index < 0 || index >= s.Length)
+
+ if (index < 0 || index >= s.Length)
{
throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
}
-
+
Contract.EndContractBlock();
- return (sbyte) (InternalGetDigitValues(InternalConvertToUtf32(s, index)) & 0x00FF);
+ return (sbyte)(InternalGetDigitValues(InternalConvertToUtf32(s, index)) & 0x00FF);
}
public static UnicodeCategory GetUnicodeCategory(char ch)
diff --git a/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs
index 271d9802ce..5002555384 100644
--- a/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs
@@ -42,7 +42,6 @@ namespace System.Globalization
internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MinSupportedDateTime
{
get
@@ -52,7 +51,6 @@ namespace System.Globalization
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MaxSupportedDateTime
{
get
@@ -318,9 +316,9 @@ namespace System.Globalization
}
}
- internal override int GetYearInfo(int LunarYear, int Index)
+ internal override int GetYearInfo(int lunarYear, int index)
{
- if ((LunarYear < MIN_LUNISOLAR_YEAR) || (LunarYear > MAX_LUNISOLAR_YEAR))
+ if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
{
throw new ArgumentOutOfRangeException(
"year",
@@ -330,7 +328,7 @@ namespace System.Globalization
}
Contract.EndContractBlock();
- return s_yinfo[LunarYear - MIN_LUNISOLAR_YEAR, Index];
+ return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
}
internal override int GetYear(int year, DateTime time)
@@ -362,7 +360,6 @@ namespace System.Globalization
{
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetEra(DateTime time)
{
CheckTicksRange(time.Ticks);
@@ -387,7 +384,6 @@ namespace System.Globalization
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override int[] Eras
{
get
diff --git a/src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs b/src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs
index 4ebaf9cb10..d4936522dd 100644
--- a/src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs
+++ b/src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs
@@ -351,7 +351,7 @@ namespace System.Globalization
private unsafe SortKey CreateSortKey(String source, CompareOptions options)
{
- if (source==null) { throw new ArgumentNullException(nameof(source)); }
+ if (source == null) { throw new ArgumentNullException(nameof(source)); }
Contract.EndContractBlock();
if ((options & ValidSortkeyCtorMaskOffFlags) != 0)
@@ -362,7 +362,7 @@ namespace System.Globalization
throw new NotImplementedException();
}
- private static unsafe bool IsSortable(char *text, int length)
+ private static unsafe bool IsSortable(char* text, int length)
{
// CompareInfo c = CultureInfo.InvariantCulture.CompareInfo;
// return (InternalIsSortable(c.m_dataHandle, c.m_handleOrigin, c.m_sortName, text, text.Length));
diff --git a/src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs b/src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs
index 7f2f17d9f5..ba96189458 100644
--- a/src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs
+++ b/src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs
@@ -24,7 +24,6 @@ namespace System.Globalization
/// This method uses the sRealName field (which is initialized by the constructor before this is called) to
/// initialize the rest of the state of CultureData based on the underlying OS globalization library.
/// </summary>
- [SecuritySafeCritical]
private unsafe bool InitCultureData()
{
Debug.Assert(_sRealName != null);
@@ -87,7 +86,6 @@ namespace System.Globalization
return true;
}
- [SecuritySafeCritical]
internal static bool GetLocaleName(string localeName, out string windowsName)
{
// Get the locale name from ICU
@@ -104,7 +102,6 @@ namespace System.Globalization
return true;
}
- [SecuritySafeCritical]
internal static bool GetDefaultLocaleName(out string windowsName)
{
// Get the default (system) locale name from ICU
@@ -129,7 +126,6 @@ namespace System.Globalization
// For LOCALE_SPARENT we need the option of using the "real" name (forcing neutral names) instead of the
// "windows" name, which can be specific for downlevel (< windows 7) os's.
- [SecuritySafeCritical]
private string GetLocaleInfo(string localeName, LocaleStringData type)
{
Debug.Assert(localeName != null, "[CultureData.GetLocaleInfo] Expected localeName to be not be null");
@@ -155,7 +151,6 @@ namespace System.Globalization
return StringBuilderCache.GetStringAndRelease(sb);
}
- [SecuritySafeCritical]
private int GetLocaleInfo(LocaleNumberData type)
{
Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo(LocaleNumberData)] Expected _sWindowsName to be populated already");
@@ -179,7 +174,6 @@ namespace System.Globalization
return value;
}
- [SecuritySafeCritical]
private int[] GetLocaleInfo(LocaleGroupingData type)
{
Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo(LocaleGroupingData)] Expected _sWindowsName to be populated already");
@@ -205,7 +199,6 @@ namespace System.Globalization
return GetTimeFormatString(false);
}
- [SecuritySafeCritical]
private string GetTimeFormatString(bool shortFormat)
{
Debug.Assert(_sWindowsName != null, "[CultureData.GetTimeFormatString(bool shortFormat)] Expected _sWindowsName to be populated already");
diff --git a/src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs b/src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs
index d1c99da607..0c264e5f8b 100644
--- a/src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs
+++ b/src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs
@@ -663,11 +663,10 @@ namespace System.Globalization
{
get { throw new NotImplementedException(); }
}
-
+
internal bool IsReplacementCulture
{
get { throw new NotImplementedException(); }
}
-
}
}
diff --git a/src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs b/src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs
index 64782d28c0..d296ad88e5 100644
--- a/src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs
+++ b/src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs
@@ -3,14 +3,13 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Threading;
using System.Runtime.Serialization;
+using System.Threading;
namespace System.Globalization
{
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
- public partial class CultureNotFoundException : ArgumentException, ISerializable
+ public class CultureNotFoundException : ArgumentException, ISerializable
{
private string _invalidCultureName; // unrecognized culture name
private int? _invalidCultureId; // unrecognized culture Lcid
@@ -66,14 +65,8 @@ namespace System.Globalization
_invalidCultureName = (string)info.GetValue("InvalidCultureName", typeof(string));
}
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
- if (info == null)
- {
- throw new ArgumentNullException(nameof(info));
- }
-
base.GetObjectData(info, context);
info.AddValue("InvalidCultureId", _invalidCultureId, typeof(int?));
info.AddValue("InvalidCultureName", _invalidCultureName, typeof(string));
diff --git a/src/mscorlib/corefx/System/Globalization/CultureTypes.cs b/src/mscorlib/corefx/System/Globalization/CultureTypes.cs
index 80b588aabb..35ddff6086 100644
--- a/src/mscorlib/corefx/System/Globalization/CultureTypes.cs
+++ b/src/mscorlib/corefx/System/Globalization/CultureTypes.cs
@@ -7,7 +7,7 @@
// the rest are obsolete or not valid on Linux
namespace System.Globalization
-{
+{
[Serializable]
[Flags]
public enum CultureTypes
@@ -25,4 +25,4 @@ namespace System.Globalization
[Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
FrameworkCultures = 0x0040, // will return only the v2 cultures marked as Framework culture.
}
-}
+}
diff --git a/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs b/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs
index 216fc603d0..b79ce90424 100644
--- a/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs
@@ -514,7 +514,6 @@ namespace System.Globalization
public String AMDesignator
{
- // auto-generated
get
{
if (this.amDesignator == null)
@@ -1031,7 +1030,6 @@ namespace System.Globalization
public String PMDesignator
{
- // auto-generated
get
{
if (this.pmDesignator == null)
@@ -2163,7 +2161,7 @@ namespace System.Globalization
//
// Positive TimeSpan Pattern
//
-
+ [NonSerialized]
private string _fullTimeSpanPositivePattern;
internal String FullTimeSpanPositivePattern
{
@@ -2187,7 +2185,7 @@ namespace System.Globalization
//
// Negative TimeSpan Pattern
//
-
+ [NonSerialized]
private string _fullTimeSpanNegativePattern;
internal String FullTimeSpanNegativePattern
{
@@ -2343,7 +2341,7 @@ namespace System.Globalization
//
// DateTimeFormatInfo tokenizer. This is used by DateTime.Parse() to break input string into tokens.
//
-
+ [NonSerialized]
private TokenHashValue[] _dtfiTokenHash;
private const int TOKEN_HASH_SIZE = 199;
diff --git a/src/mscorlib/corefx/System/Globalization/DigitShapes.cs b/src/mscorlib/corefx/System/Globalization/DigitShapes.cs
index 7e40033a2f..0e4dcc87c3 100644
--- a/src/mscorlib/corefx/System/Globalization/DigitShapes.cs
+++ b/src/mscorlib/corefx/System/Globalization/DigitShapes.cs
@@ -5,6 +5,7 @@
//
// The enumeration constants used in NumberFormatInfo.DigitSubstitution.
//
+
namespace System.Globalization
{
[Serializable]
diff --git a/src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs
index 84a44a990d..f82fad8e5b 100644
--- a/src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs
@@ -14,7 +14,6 @@ namespace System.Globalization
////////////////////////////////////////////////////////////////////////////
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public abstract class EastAsianLunisolarCalendar : Calendar
{
internal const int LeapMonth = 0;
diff --git a/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs b/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs
index c2ed2e012b..be5b65b385 100644
--- a/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs
@@ -19,7 +19,6 @@ namespace System.Globalization
// 1 BeforeCurrentEra (BC)
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public class GregorianCalendar : Calendar
{
@@ -66,7 +65,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MinSupportedDateTime
{
get
@@ -75,7 +73,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MaxSupportedDateTime
{
get
@@ -84,7 +81,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override CalendarAlgorithmType AlgorithmType
{
get
@@ -510,7 +506,6 @@ namespace System.Globalization
// if this calendar does not have leap month, or this year is not a leap year.
//
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetLeapMonth(int year, int era)
{
if (era != CurrentEra && era != ADEra)
diff --git a/src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs b/src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs
index 7e63708382..b4f54f8fbb 100644
--- a/src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs
@@ -63,7 +63,6 @@ namespace System.Globalization
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public class HebrewCalendar : Calendar
{
public static readonly int HebrewEra = 1;
diff --git a/src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs b/src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs
index 5f46dce61d..869b809bff 100644
--- a/src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs
+++ b/src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs
@@ -8,9 +8,10 @@ namespace System.Globalization
{
public partial class HijriCalendar : Calendar
{
- private static int GetHijriDateAdjustment()
+ private int GetHijriDateAdjustment()
{
- if (_hijriAdvance == Int32.MinValue) {
+ if (_hijriAdvance == Int32.MinValue)
+ {
// Never been set before. Use the system value from registry.
_hijriAdvance = GetAdvanceHijriDate();
}
@@ -36,11 +37,13 @@ namespace System.Globalization
** "AddHijriDate+1" => Add +1 days to the current calculated Hijri date.
** "AddHijriDate+2" => Add +2 days to the current calculated Hijri date.
============================================================================*/
- private static int GetAdvanceHijriDate() {
+ private static int GetAdvanceHijriDate()
+ {
int hijriAdvance = 0;
Microsoft.Win32.RegistryKey key = null;
- try {
+ try
+ {
// Open in read-only mode.
// Use InternalOpenSubKey so that we avoid the security check.
key = RegistryKey.GetBaseKey(RegistryKey.HKEY_CURRENT_USER).OpenSubKey(InternationalRegKey, false);
@@ -49,21 +52,28 @@ namespace System.Globalization
catch (ObjectDisposedException) { return 0; }
catch (ArgumentException) { return 0; }
- if (key != null) {
- try {
+ if (key != null)
+ {
+ try
+ {
Object value = key.InternalGetValue(HijriAdvanceRegKeyEntry, null, false, false);
- if (value == null) {
+ if (value == null)
+ {
return (0);
}
String str = value.ToString();
- if (String.Compare(str, 0, HijriAdvanceRegKeyEntry, 0, HijriAdvanceRegKeyEntry.Length, StringComparison.OrdinalIgnoreCase) == 0) {
+ if (String.Compare(str, 0, HijriAdvanceRegKeyEntry, 0, HijriAdvanceRegKeyEntry.Length, StringComparison.OrdinalIgnoreCase) == 0)
+ {
if (str.Length == HijriAdvanceRegKeyEntry.Length)
hijriAdvance = -1;
- else {
+ else
+ {
str = str.Substring(HijriAdvanceRegKeyEntry.Length);
- try {
+ try
+ {
int advance = Int32.Parse(str.ToString(), CultureInfo.InvariantCulture);
- if ((advance >= MinAdvancedHijri) && (advance <= MaxAdvancedHijri)) {
+ if ((advance >= MinAdvancedHijri) && (advance <= MaxAdvancedHijri))
+ {
hijriAdvance = advance;
}
}
@@ -75,10 +85,10 @@ namespace System.Globalization
}
}
}
- finally {
+ finally
+ {
key.Close();
}
-
}
return (hijriAdvance);
}
diff --git a/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs b/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs
index 156b2104bd..0c72d9eaf5 100644
--- a/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs
@@ -45,7 +45,6 @@ namespace System.Globalization
*/
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public partial class HijriCalendar : Calendar
{
public static readonly int HijriEra = 1;
@@ -72,7 +71,6 @@ namespace System.Globalization
internal static readonly DateTime calendarMaxValue = DateTime.MaxValue;
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MinSupportedDateTime
{
get
@@ -82,7 +80,6 @@ namespace System.Globalization
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MaxSupportedDateTime
{
get
@@ -91,7 +88,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override CalendarAlgorithmType AlgorithmType
{
get
@@ -565,7 +561,6 @@ namespace System.Globalization
// if this calendar does not have leap month, or this year is not a leap year.
//
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetLeapMonth(int year, int era)
{
CheckYearRange(year, era);
diff --git a/src/mscorlib/corefx/System/Globalization/IdnMapping.Windows.cs b/src/mscorlib/corefx/System/Globalization/IdnMapping.Windows.cs
index f39457b750..3d3292e3db 100644
--- a/src/mscorlib/corefx/System/Globalization/IdnMapping.Windows.cs
+++ b/src/mscorlib/corefx/System/Globalization/IdnMapping.Windows.cs
@@ -7,7 +7,7 @@ using System.Runtime.InteropServices;
namespace System.Globalization
{
- sealed partial class IdnMapping
+ public sealed partial class IdnMapping
{
private unsafe string GetAsciiCore(char* unicode, int count)
{
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs
index bbde320041..a83c4fad9e 100644
--- a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs
+++ b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs
@@ -33,7 +33,7 @@ namespace System.Globalization
// Look in the registry key and see if we can find any ranges
int iFoundEras = 0;
EraInfo[] registryEraRanges = null;
-
+
try
{
// Need to access registry
@@ -59,7 +59,7 @@ namespace System.Globalization
// Remember we found one.
registryEraRanges[iFoundEras] = era;
- iFoundEras++;
+ iFoundEras++;
}
}
}
@@ -109,7 +109,7 @@ namespace System.Globalization
else
{
// Rest are until the next era (remember most recent era is first in array)
- registryEraRanges[i].maxEraYear = registryEraRanges[i-1].yearOffset + 1 - registryEraRanges[i].yearOffset;
+ registryEraRanges[i].maxEraYear = registryEraRanges[i - 1].yearOffset + 1 - registryEraRanges[i].yearOffset;
}
}
@@ -147,7 +147,7 @@ namespace System.Globalization
{
// Need inputs
if (value == null || data == null) return null;
-
+
//
// Get Date
//
@@ -159,9 +159,9 @@ namespace System.Globalization
int month;
int day;
- if (!Int32.TryParse(value.Substring(0,4), NumberStyles.None, NumberFormatInfo.InvariantInfo, out year) ||
- !Int32.TryParse(value.Substring(5,2), NumberStyles.None, NumberFormatInfo.InvariantInfo, out month) ||
- !Int32.TryParse(value.Substring(8,2), NumberStyles.None, NumberFormatInfo.InvariantInfo, out day))
+ if (!Int32.TryParse(value.Substring(0, 4), NumberStyles.None, NumberFormatInfo.InvariantInfo, out year) ||
+ !Int32.TryParse(value.Substring(5, 2), NumberStyles.None, NumberFormatInfo.InvariantInfo, out month) ||
+ !Int32.TryParse(value.Substring(8, 2), NumberStyles.None, NumberFormatInfo.InvariantInfo, out day))
{
// Couldn't convert integer, fail
return null;
@@ -171,7 +171,7 @@ namespace System.Globalization
// Get Strings
//
// Needs to be a certain length e_a_E_A at least (7 chars, exactly 4 groups)
- String[] names = data.Split(new char[] {'_'});
+ String[] names = data.Split('_');
// Should have exactly 4 parts
// 0 - Era Name
@@ -192,18 +192,18 @@ namespace System.Globalization
// Note that the era # and max era year need cleaned up after sorting
// Don't use the full English Era Name (names[2])
//
- return new EraInfo( 0, year, month, day, year - 1, 1, 0,
+ return new EraInfo(0, year, month, day, year - 1, 1, 0,
names[0], names[1], names[3]);
}
// PAL Layer ends here
- private static string[] JapaneseErasEnglishNames = new String[] { "M", "T", "S", "H" };
+ private static string[] s_japaneseErasEnglishNames = new String[] { "M", "T", "S", "H" };
private static string GetJapaneseEnglishEraName(int era)
{
Debug.Assert(era > 0);
- return era <= JapaneseErasEnglishNames.Length ? JapaneseErasEnglishNames[era - 1] : " ";
+ return era <= s_japaneseErasEnglishNames.Length ? s_japaneseErasEnglishNames[era - 1] : " ";
}
}
}
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs
index 0b0fa77fc0..f0216c8f51 100644
--- a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs
@@ -39,13 +39,11 @@ namespace System.Globalization
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public partial class JapaneseCalendar : Calendar
{
internal static readonly DateTime calendarMinValue = new DateTime(1868, 9, 8);
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MinSupportedDateTime
{
get
@@ -54,7 +52,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MaxSupportedDateTime
{
get
@@ -63,7 +60,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override CalendarAlgorithmType AlgorithmType
{
get
@@ -233,7 +229,6 @@ namespace System.Globalization
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
{
return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
@@ -281,7 +276,6 @@ namespace System.Globalization
// if this calendar does not have leap month, or this year is not a leap year.
//
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetLeapMonth(int year, int era)
{
return (helper.GetLeapMonth(year, era));
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/JapaneseLunisolarCalendar.cs
index ecdaced2d7..cc3d34954d 100644
--- a/src/mscorlib/corefx/System/Globalization/JapaneseLunisolarCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/JapaneseLunisolarCalendar.cs
@@ -206,9 +206,9 @@ namespace System.Globalization
}
}
- internal override int GetYearInfo(int LunarYear, int Index)
+ internal override int GetYearInfo(int lunarYear, int index)
{
- if ((LunarYear < MIN_LUNISOLAR_YEAR) || (LunarYear > MAX_LUNISOLAR_YEAR))
+ if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
{
throw new ArgumentOutOfRangeException(
"year",
@@ -220,7 +220,7 @@ namespace System.Globalization
}
Contract.EndContractBlock();
- return s_yinfo[LunarYear - MIN_LUNISOLAR_YEAR, Index];
+ return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
}
internal override int GetYear(int year, DateTime time)
diff --git a/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs b/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs
index a4277c6d49..43e6ad07a2 100644
--- a/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs
@@ -19,7 +19,6 @@ namespace System.Globalization
//* Julia 0001/01/03 9999/10/19
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public class JulianCalendar : Calendar
{
public static readonly int JulianEra = 1;
@@ -49,7 +48,6 @@ namespace System.Globalization
internal int MaxYear = 9999;
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MinSupportedDateTime
{
get
@@ -58,7 +56,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MaxSupportedDateTime
{
get
@@ -67,7 +64,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override CalendarAlgorithmType AlgorithmType
{
get
@@ -346,7 +342,6 @@ namespace System.Globalization
// if this calendar does not have leap month, or this year is not a leap year.
//
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetLeapMonth(int year, int era)
{
CheckYearEraRange(year, era);
diff --git a/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs b/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs
index 27d0aa812a..b015aa0716 100644
--- a/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs
@@ -25,7 +25,6 @@ namespace System.Globalization
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public class KoreanCalendar : Calendar
{
//
@@ -51,7 +50,6 @@ namespace System.Globalization
internal GregorianCalendarHelper helper;
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MinSupportedDateTime
{
get
@@ -60,7 +58,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MaxSupportedDateTime
{
get
@@ -69,7 +66,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override CalendarAlgorithmType AlgorithmType
{
get
@@ -160,7 +156,6 @@ namespace System.Globalization
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
{
return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
@@ -199,7 +194,6 @@ namespace System.Globalization
// if this calendar does not have leap month, or this year is not a leap year.
//
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetLeapMonth(int year, int era)
{
return (helper.GetLeapMonth(year, era));
diff --git a/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs
index 07d85a461e..6d091285b2 100644
--- a/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs
@@ -1251,9 +1251,9 @@ namespace System.Globalization
}
}
- internal override int GetYearInfo(int LunarYear, int Index)
+ internal override int GetYearInfo(int lunarYear, int index)
{
- if ((LunarYear < MIN_LUNISOLAR_YEAR) || (LunarYear > MAX_LUNISOLAR_YEAR))
+ if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
{
throw new ArgumentOutOfRangeException(
"year",
@@ -1264,7 +1264,7 @@ namespace System.Globalization
MAX_LUNISOLAR_YEAR));
}
Contract.EndContractBlock();
- return s_yinfo[LunarYear - MIN_LUNISOLAR_YEAR, Index];
+ return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
}
internal override int GetYear(int year, DateTime time)
diff --git a/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs b/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs
index 813554fd21..54cf492135 100644
--- a/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs
@@ -289,7 +289,7 @@ namespace System.Globalization
if (value < 0 || value > 99)
{
throw new ArgumentOutOfRangeException(
- "CurrencyDecimalDigits",
+ nameof(CurrencyDecimalDigits),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -357,14 +357,14 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("CurrencyGroupSizes",
+ throw new ArgumentNullException(nameof(CurrencyGroupSizes),
SR.ArgumentNull_Obj);
}
Contract.EndContractBlock();
VerifyWritable();
Int32[] inputSizes = (Int32[])value.Clone();
- CheckGroupSize("CurrencyGroupSizes", inputSizes);
+ CheckGroupSize(nameof(CurrencyGroupSizes), inputSizes);
currencyGroupSizes = inputSizes;
}
}
@@ -381,14 +381,14 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("NumberGroupSizes",
+ throw new ArgumentNullException(nameof(NumberGroupSizes),
SR.ArgumentNull_Obj);
}
Contract.EndContractBlock();
VerifyWritable();
Int32[] inputSizes = (Int32[])value.Clone();
- CheckGroupSize("NumberGroupSizes", inputSizes);
+ CheckGroupSize(nameof(NumberGroupSizes), inputSizes);
numberGroupSizes = inputSizes;
}
}
@@ -422,7 +422,7 @@ namespace System.Globalization
set
{
VerifyWritable();
- VerifyGroupSeparator(value, "CurrencyGroupSeparator");
+ VerifyGroupSeparator(value, nameof(CurrencyGroupSeparator));
currencyGroupSeparator = value;
}
}
@@ -435,7 +435,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("CurrencySymbol",
+ throw new ArgumentNullException(nameof(CurrencySymbol),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -475,7 +475,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("NaNSymbol",
+ throw new ArgumentNullException(nameof(NaNSymbol),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -494,7 +494,7 @@ namespace System.Globalization
if (value < 0 || value > 15)
{
throw new ArgumentOutOfRangeException(
- "CurrencyNegativePattern",
+ nameof(CurrencyNegativePattern),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -519,7 +519,7 @@ namespace System.Globalization
if (value < 0 || value > 4)
{
throw new ArgumentOutOfRangeException(
- "NumberNegativePattern",
+ nameof(NumberNegativePattern),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -544,7 +544,7 @@ namespace System.Globalization
if (value < 0 || value > 3)
{
throw new ArgumentOutOfRangeException(
- "PercentPositivePattern",
+ nameof(PercentPositivePattern),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -569,7 +569,7 @@ namespace System.Globalization
if (value < 0 || value > 11)
{
throw new ArgumentOutOfRangeException(
- "PercentNegativePattern",
+ nameof(PercentNegativePattern),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -593,7 +593,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("NegativeInfinitySymbol",
+ throw new ArgumentNullException(nameof(NegativeInfinitySymbol),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -610,7 +610,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("NegativeSign",
+ throw new ArgumentNullException(nameof(NegativeSign),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -628,7 +628,7 @@ namespace System.Globalization
if (value < 0 || value > 99)
{
throw new ArgumentOutOfRangeException(
- "NumberDecimalDigits",
+ nameof(NumberDecimalDigits),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -648,7 +648,7 @@ namespace System.Globalization
set
{
VerifyWritable();
- VerifyDecimalSeparator(value, "NumberDecimalSeparator");
+ VerifyDecimalSeparator(value, nameof(NumberDecimalSeparator));
numberDecimalSeparator = value;
}
}
@@ -660,7 +660,7 @@ namespace System.Globalization
set
{
VerifyWritable();
- VerifyGroupSeparator(value, "NumberGroupSeparator");
+ VerifyGroupSeparator(value, nameof(NumberGroupSeparator));
numberGroupSeparator = value;
}
}
@@ -674,7 +674,7 @@ namespace System.Globalization
if (value < 0 || value > 3)
{
throw new ArgumentOutOfRangeException(
- "CurrencyPositivePattern",
+ nameof(CurrencyPositivePattern),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -698,7 +698,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("PositiveInfinitySymbol",
+ throw new ArgumentNullException(nameof(PositiveInfinitySymbol),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -715,7 +715,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("PositiveSign",
+ throw new ArgumentNullException(nameof(PositiveSign),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -733,7 +733,7 @@ namespace System.Globalization
if (value < 0 || value > 99)
{
throw new ArgumentOutOfRangeException(
- "PercentDecimalDigits",
+ nameof(PercentDecimalDigits),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -753,7 +753,7 @@ namespace System.Globalization
set
{
VerifyWritable();
- VerifyDecimalSeparator(value, "PercentDecimalSeparator");
+ VerifyDecimalSeparator(value, nameof(PercentDecimalSeparator));
percentDecimalSeparator = value;
}
}
@@ -765,7 +765,7 @@ namespace System.Globalization
set
{
VerifyWritable();
- VerifyGroupSeparator(value, "PercentGroupSeparator");
+ VerifyGroupSeparator(value, nameof(PercentGroupSeparator));
percentGroupSeparator = value;
}
}
@@ -781,7 +781,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("PercentSymbol",
+ throw new ArgumentNullException(nameof(PercentSymbol),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -798,7 +798,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("PerMilleSymbol",
+ throw new ArgumentNullException(nameof(PerMilleSymbol),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -813,7 +813,7 @@ namespace System.Globalization
set
{
VerifyWritable();
- VerifyNativeDigits(value, "NativeDigits");
+ VerifyNativeDigits(value, nameof(NativeDigits));
nativeDigits = value;
}
}
@@ -824,7 +824,7 @@ namespace System.Globalization
set
{
VerifyWritable();
- VerifyDigitSubstitution(value, "DigitSubstitution");
+ VerifyDigitSubstitution(value, nameof(DigitSubstitution));
digitSubstitution = (int) value;
}
}
diff --git a/src/mscorlib/corefx/System/Globalization/RegionInfo.cs b/src/mscorlib/corefx/System/Globalization/RegionInfo.cs
index 0645ded0ab..15679d24dd 100644
--- a/src/mscorlib/corefx/System/Globalization/RegionInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/RegionInfo.cs
@@ -87,7 +87,6 @@ namespace System.Globalization
SetName(name);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public RegionInfo(int culture)
{
if (culture == CultureInfo.LOCALE_INVARIANT) //The InvariantCulture has no matching region
@@ -132,7 +131,6 @@ namespace System.Globalization
[OnSerializing]
private void OnSerializing(StreamingContext ctx) { }
- [System.Security.SecurityCritical] // auto-generated
[OnDeserialized]
private void OnDeserialized(StreamingContext ctx)
{
diff --git a/src/mscorlib/corefx/System/Globalization/SortKey.cs b/src/mscorlib/corefx/System/Globalization/SortKey.cs
index fc151fa37e..9e22a6f332 100644
--- a/src/mscorlib/corefx/System/Globalization/SortKey.cs
+++ b/src/mscorlib/corefx/System/Globalization/SortKey.cs
@@ -19,7 +19,6 @@ namespace System.Globalization {
using System.Diagnostics;
using System.Diagnostics.Contracts;
- [System.Runtime.InteropServices.ComVisible(true)]
[Serializable]
public partial class SortKey
{
diff --git a/src/mscorlib/corefx/System/Globalization/SortVersion.cs b/src/mscorlib/corefx/System/Globalization/SortVersion.cs
index 72aa6d6b7b..983179c149 100644
--- a/src/mscorlib/corefx/System/Globalization/SortVersion.cs
+++ b/src/mscorlib/corefx/System/Globalization/SortVersion.cs
@@ -5,7 +5,7 @@
using System;
using System.Diagnostics.Contracts;
-namespace System.Globalization
+namespace System.Globalization
{
[Serializable]
public sealed class SortVersion : IEquatable<SortVersion>
@@ -13,48 +13,48 @@ namespace System.Globalization
private int _nlsVersion;
private Guid _sortId;
- public int FullVersion
+ public int FullVersion
{
- get
+ get
{
return _nlsVersion;
}
}
- public Guid SortId
+ public Guid SortId
{
- get
+ get
{
return _sortId;
}
}
- public SortVersion(int fullVersion, Guid sortId)
- {
+ public SortVersion(int fullVersion, Guid sortId)
+ {
_sortId = sortId;
_nlsVersion = fullVersion;
}
- internal SortVersion(int nlsVersion, int effectiveId, Guid customVersion)
+ internal SortVersion(int nlsVersion, int effectiveId, Guid customVersion)
{
_nlsVersion = nlsVersion;
- if (customVersion == Guid.Empty)
+ if (customVersion == Guid.Empty)
{
- byte b1 = (byte) (effectiveId >> 24);
- byte b2 = (byte) ((effectiveId & 0x00FF0000) >> 16);
- byte b3 = (byte) ((effectiveId & 0x0000FF00) >> 8);
- byte b4 = (byte) (effectiveId & 0xFF);
- customVersion = new Guid(0,0,0,0,0,0,0,b1,b2,b3,b4);
+ byte b1 = (byte)(effectiveId >> 24);
+ byte b2 = (byte)((effectiveId & 0x00FF0000) >> 16);
+ byte b3 = (byte)((effectiveId & 0x0000FF00) >> 8);
+ byte b4 = (byte)(effectiveId & 0xFF);
+ customVersion = new Guid(0, 0, 0, 0, 0, 0, 0, b1, b2, b3, b4);
}
_sortId = customVersion;
}
- public override bool Equals(object obj)
+ public override bool Equals(object obj)
{
SortVersion n = obj as SortVersion;
- if (n != null)
+ if (n != null)
{
return this.Equals(n);
}
@@ -62,9 +62,9 @@ namespace System.Globalization
return false;
}
- public bool Equals(SortVersion other)
+ public bool Equals(SortVersion other)
{
- if (other == null)
+ if (other == null)
{
return false;
}
@@ -72,19 +72,19 @@ namespace System.Globalization
return _nlsVersion == other._nlsVersion && _sortId == other._sortId;
}
- public override int GetHashCode()
- {
- return _nlsVersion * 7 | _sortId.GetHashCode();
+ public override int GetHashCode()
+ {
+ return _nlsVersion * 7 | _sortId.GetHashCode();
}
- public static bool operator ==(SortVersion left, SortVersion right)
+ public static bool operator ==(SortVersion left, SortVersion right)
{
- if (((object) left) != null)
+ if (((object)left) != null)
{
return left.Equals(right);
}
- if (((object) right) != null)
+ if (((object)right) != null)
{
return right.Equals(left);
}
@@ -93,7 +93,7 @@ namespace System.Globalization
return true;
}
- public static bool operator !=(SortVersion left, SortVersion right)
+ public static bool operator !=(SortVersion left, SortVersion right)
{
return !(left == right);
}
diff --git a/src/mscorlib/corefx/System/Globalization/StringInfo.cs b/src/mscorlib/corefx/System/Globalization/StringInfo.cs
index 7558002413..f1dd30561b 100644
--- a/src/mscorlib/corefx/System/Globalization/StringInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/StringInfo.cs
@@ -20,7 +20,6 @@ using System.Runtime.Serialization;
namespace System.Globalization
{
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public class StringInfo
{
[OptionalField(VersionAdded = 2)]
@@ -53,7 +52,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override bool Equals(Object value)
{
StringInfo that = value as StringInfo;
@@ -64,7 +62,6 @@ namespace System.Globalization
return (false);
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetHashCode()
{
return _str.GetHashCode();
diff --git a/src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs b/src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs
index 36edd5b2fd..2e735e0cb9 100644
--- a/src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs
@@ -22,7 +22,6 @@ namespace System.Globalization
============================================================================*/
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public class TaiwanCalendar : Calendar
{
//
@@ -65,7 +64,6 @@ namespace System.Globalization
internal static readonly DateTime calendarMinValue = new DateTime(1912, 1, 1);
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MinSupportedDateTime
{
get
@@ -74,7 +72,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MaxSupportedDateTime
{
get
@@ -83,7 +80,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override CalendarAlgorithmType AlgorithmType
{
get
@@ -166,7 +162,6 @@ namespace System.Globalization
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
{
return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
@@ -205,7 +200,6 @@ namespace System.Globalization
// if this calendar does not have leap month, or this year is not a leap year.
//
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetLeapMonth(int year, int era)
{
return (helper.GetLeapMonth(year, era));
diff --git a/src/mscorlib/corefx/System/Globalization/TaiwanLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/TaiwanLunisolarCalendar.cs
index 42b7f2473b..1f75ac9a04 100644
--- a/src/mscorlib/corefx/System/Globalization/TaiwanLunisolarCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/TaiwanLunisolarCalendar.cs
@@ -264,9 +264,9 @@ namespace System.Globalization
}
}
- internal override int GetYearInfo(int LunarYear, int Index)
+ internal override int GetYearInfo(int lunarYear, int index)
{
- if ((LunarYear < MIN_LUNISOLAR_YEAR) || (LunarYear > MAX_LUNISOLAR_YEAR))
+ if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
{
throw new ArgumentOutOfRangeException(
"year",
@@ -278,7 +278,7 @@ namespace System.Globalization
}
Contract.EndContractBlock();
- return s_yinfo[LunarYear - MIN_LUNISOLAR_YEAR, Index];
+ return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
}
internal override int GetYear(int year, DateTime time)
diff --git a/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs b/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs
index c0ffc65307..464897b03f 100644
--- a/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs
+++ b/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs
@@ -21,7 +21,6 @@ namespace System.Globalization
//
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public class TextElementEnumerator : IEnumerator
{
private String _str;
diff --git a/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs b/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
index 3d9b777f64..67836d89d6 100644
--- a/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
+++ b/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
@@ -33,7 +33,6 @@ namespace System.Globalization
{
}
- [SecuritySafeCritical]
private unsafe string ChangeCase(string s, bool toUpper)
{
Debug.Assert(s != null);
@@ -78,7 +77,6 @@ namespace System.Globalization
return result;
}
- [SecuritySafeCritical]
private unsafe char ChangeCase(char c, bool toUpper)
{
char dst = default(char);
diff --git a/src/mscorlib/corefx/System/Globalization/TextInfo.cs b/src/mscorlib/corefx/System/Globalization/TextInfo.cs
index 5bb376f19c..172bbd25b2 100644
--- a/src/mscorlib/corefx/System/Globalization/TextInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/TextInfo.cs
@@ -188,7 +188,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public int LCID
{
get
@@ -220,7 +219,6 @@ namespace System.Globalization
// Detect if the object is readonly.
//
////////////////////////////////////////////////////////////////////////
- [System.Runtime.InteropServices.ComVisible(false)]
public bool IsReadOnly
{
get { return (_isReadOnly); }
@@ -248,7 +246,6 @@ namespace System.Globalization
// readonly.
//
////////////////////////////////////////////////////////////////////////
- [System.Runtime.InteropServices.ComVisible(false)]
public static TextInfo ReadOnly(TextInfo textInfo)
{
if (textInfo == null) { throw new ArgumentNullException(nameof(textInfo)); }
diff --git a/src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs b/src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs
index 8ebbfa0a69..9e6e30406c 100644
--- a/src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs
@@ -21,7 +21,6 @@ namespace System.Globalization
============================================================================*/
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public class ThaiBuddhistCalendar : Calendar
{
// Initialize our era info.
@@ -38,7 +37,6 @@ namespace System.Globalization
internal GregorianCalendarHelper helper;
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MinSupportedDateTime
{
get
@@ -47,7 +45,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override DateTime MaxSupportedDateTime
{
get
@@ -56,7 +53,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public override CalendarAlgorithmType AlgorithmType
{
get
@@ -128,7 +124,6 @@ namespace System.Globalization
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
{
return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
@@ -167,7 +162,6 @@ namespace System.Globalization
// if this calendar does not have leap month, or this year is not a leap year.
//
- [System.Runtime.InteropServices.ComVisible(false)]
public override int GetLeapMonth(int year, int era)
{
return (helper.GetLeapMonth(year, era));
diff --git a/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs b/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs
index 997c5f2316..7b47d9c02b 100644
--- a/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs
@@ -41,7 +41,7 @@ namespace System.Globalization
private static DateMapping[] InitDateMapping()
{
- short[] rawData = new short[]
+ short[] rawData = new short[]
{
//These data is taken from Tables/Excel/UmAlQura.xls please make sure that the two places are in sync
/* DaysPerM GY GM GD D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12
diff --git a/src/mscorlib/corefx/System/IO/FileStream.NetStandard17.cs b/src/mscorlib/corefx/System/IO/FileStream.NetStandard17.cs
deleted file mode 100644
index dc1385fbc0..0000000000
--- a/src/mscorlib/corefx/System/IO/FileStream.NetStandard17.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using Microsoft.Win32.SafeHandles;
-using System.Threading.Tasks;
-using System.Diagnostics;
-using System.Threading;
-
-namespace System.IO
-{
- public partial class FileStream : Stream
- {
- public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, AsyncCallback callback, object state)
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array));
- if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
- if (numBytes < 0)
- throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_NeedNonNegNum);
- if (array.Length - offset < numBytes)
- throw new ArgumentException(SR.Argument_InvalidOffLen);
-
- if (IsClosed) throw new ObjectDisposedException(SR.ObjectDisposed_FileClosed);
- if (!CanRead) throw new NotSupportedException(SR.NotSupported_UnreadableStream);
-
- if (!IsAsync)
- return base.BeginRead(array, offset, numBytes, callback, state);
- else
- return TaskToApm.Begin(ReadAsyncInternal(array, offset, numBytes, CancellationToken.None), callback, state);
- }
-
- public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback callback, object state)
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array));
- if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
- if (numBytes < 0)
- throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_NeedNonNegNum);
- if (array.Length - offset < numBytes)
- throw new ArgumentException(SR.Argument_InvalidOffLen);
-
- if (IsClosed) throw new ObjectDisposedException(SR.ObjectDisposed_FileClosed);
- if (!CanWrite) throw new NotSupportedException(SR.NotSupported_UnwritableStream);
-
- if (!IsAsync)
- return base.BeginWrite(array, offset, numBytes, callback, state);
- else
- return TaskToApm.Begin(WriteAsyncInternal(array, offset, numBytes, CancellationToken.None), callback, state);
- }
-
- public override int EndRead(IAsyncResult asyncResult)
- {
- if (asyncResult == null)
- throw new ArgumentNullException(nameof(asyncResult));
-
- if (!IsAsync)
- return base.EndRead(asyncResult);
- else
- return TaskToApm.End<int>(asyncResult);
- }
-
- public override void EndWrite(IAsyncResult asyncResult)
- {
- if (asyncResult == null)
- throw new ArgumentNullException(nameof(asyncResult));
-
- if (!IsAsync)
- base.EndWrite(asyncResult);
- else
- TaskToApm.End(asyncResult);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/FileStream.Win32.cs b/src/mscorlib/corefx/System/IO/FileStream.Win32.cs
index 350d948b00..683eef5e43 100644
--- a/src/mscorlib/corefx/System/IO/FileStream.Win32.cs
+++ b/src/mscorlib/corefx/System/IO/FileStream.Win32.cs
@@ -55,7 +55,7 @@ namespace System.IO
private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options)
{
- Interop.mincore.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
+ Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
int fAccess =
((_access & FileAccess.Read) == FileAccess.Read ? GENERIC_READ : 0) |
@@ -74,13 +74,13 @@ namespace System.IO
// For mitigating local elevation of privilege attack through named pipes
// make sure we always call CreateFile with SECURITY_ANONYMOUS so that the
// named pipe server can't impersonate a high privileged client security context
- flagsAndAttributes |= (Interop.mincore.SecurityOptions.SECURITY_SQOS_PRESENT | Interop.mincore.SecurityOptions.SECURITY_ANONYMOUS);
+ flagsAndAttributes |= (Interop.Kernel32.SecurityOptions.SECURITY_SQOS_PRESENT | Interop.Kernel32.SecurityOptions.SECURITY_ANONYMOUS);
// Don't pop up a dialog for reading from an empty floppy drive
- uint oldMode = Interop.mincore.SetErrorMode(Interop.mincore.SEM_FAILCRITICALERRORS);
+ uint oldMode = Interop.Kernel32.SetErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS);
try
{
- SafeFileHandle fileHandle = Interop.mincore.SafeCreateFile(_path, fAccess, share, ref secAttrs, mode, flagsAndAttributes, IntPtr.Zero);
+ SafeFileHandle fileHandle = Interop.Kernel32.SafeCreateFile(_path, fAccess, share, ref secAttrs, mode, flagsAndAttributes, IntPtr.Zero);
fileHandle.IsAsync = _useAsyncIO;
if (fileHandle.IsInvalid)
@@ -92,8 +92,8 @@ namespace System.IO
// probably be consistent w/ every other directory.
int errorCode = Marshal.GetLastWin32Error();
- if (errorCode == Interop.mincore.Errors.ERROR_PATH_NOT_FOUND && _path.Equals(Directory.InternalGetDirectoryRoot(_path)))
- errorCode = Interop.mincore.Errors.ERROR_ACCESS_DENIED;
+ if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && _path.Equals(Directory.InternalGetDirectoryRoot(_path)))
+ errorCode = Interop.Errors.ERROR_ACCESS_DENIED;
throw Win32Marshal.GetExceptionForWin32Error(errorCode, _path);
}
@@ -102,7 +102,7 @@ namespace System.IO
}
finally
{
- Interop.mincore.SetErrorMode(oldMode);
+ Interop.Kernel32.SetErrorMode(oldMode);
}
}
@@ -112,8 +112,8 @@ namespace System.IO
// constructors that take a String. Everyone else can call
// CreateFile themselves then use the constructor that takes an
// IntPtr. Disallows "con:", "com1:", "lpt1:", etc.
- int fileType = Interop.mincore.GetFileType(_fileHandle);
- if (fileType != Interop.mincore.FileTypes.FILE_TYPE_DISK)
+ int fileType = Interop.Kernel32.GetFileType(_fileHandle);
+ if (fileType != Interop.Kernel32.FileTypes.FILE_TYPE_DISK)
{
_fileHandle.Dispose();
throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
@@ -163,11 +163,11 @@ namespace System.IO
private void InitFromHandle(SafeFileHandle handle)
{
- int handleType = Interop.mincore.GetFileType(_fileHandle);
- Debug.Assert(handleType == Interop.mincore.FileTypes.FILE_TYPE_DISK || handleType == Interop.mincore.FileTypes.FILE_TYPE_PIPE || handleType == Interop.mincore.FileTypes.FILE_TYPE_CHAR, "FileStream was passed an unknown file type!");
+ int handleType = Interop.Kernel32.GetFileType(_fileHandle);
+ Debug.Assert(handleType == Interop.Kernel32.FileTypes.FILE_TYPE_DISK || handleType == Interop.Kernel32.FileTypes.FILE_TYPE_PIPE || handleType == Interop.Kernel32.FileTypes.FILE_TYPE_CHAR, "FileStream was passed an unknown file type!");
- _canSeek = handleType == Interop.mincore.FileTypes.FILE_TYPE_DISK;
- _isPipe = handleType == Interop.mincore.FileTypes.FILE_TYPE_PIPE;
+ _canSeek = handleType == Interop.Kernel32.FileTypes.FILE_TYPE_DISK;
+ _isPipe = handleType == Interop.Kernel32.FileTypes.FILE_TYPE_PIPE;
// This is necessary for async IO using IO Completion ports via our
// managed Threadpool API's. This calls the OS's
@@ -196,7 +196,7 @@ namespace System.IO
}
else if (!_useAsyncIO)
{
- if (handleType != Interop.mincore.FileTypes.FILE_TYPE_PIPE)
+ if (handleType != Interop.Kernel32.FileTypes.FILE_TYPE_PIPE)
VerifyHandleIsSync();
}
@@ -211,13 +211,13 @@ namespace System.IO
return handle.IsAsync.HasValue ? handle.IsAsync.Value : false;
}
- private unsafe static Interop.mincore.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
+ private unsafe static Interop.Kernel32.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
{
- Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
+ Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = default(Interop.Kernel32.SECURITY_ATTRIBUTES);
if ((share & FileShare.Inheritable) != 0)
{
- secAttrs = new Interop.mincore.SECURITY_ATTRIBUTES();
- secAttrs.nLength = (uint)sizeof(Interop.mincore.SECURITY_ATTRIBUTES);
+ secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES();
+ secAttrs.nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES);
secAttrs.bInheritHandle = Interop.BOOL.TRUE;
}
@@ -234,7 +234,7 @@ namespace System.IO
// cause an app to block incorrectly, introducing a deadlock (depending
// on whether a write will wake up an already-blocked thread or this
// Win32FileStream's thread).
- Debug.Assert(Interop.mincore.GetFileType(_fileHandle) != Interop.mincore.FileTypes.FILE_TYPE_PIPE);
+ Debug.Assert(Interop.Kernel32.GetFileType(_fileHandle) != Interop.Kernel32.FileTypes.FILE_TYPE_PIPE);
byte* bytes = stackalloc byte[1];
int numBytesReadWritten;
@@ -246,11 +246,11 @@ namespace System.IO
// accidentally read synchronously from an async pipe.
if ((_access & FileAccess.Read) != 0) // don't use the virtual CanRead or CanWrite, as this may be used in the ctor
{
- r = Interop.mincore.ReadFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
+ r = Interop.Kernel32.ReadFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
}
else if ((_access & FileAccess.Write) != 0) // don't use the virtual CanRead or CanWrite, as this may be used in the ctor
{
- r = Interop.mincore.WriteFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
+ r = Interop.Kernel32.WriteFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
}
if (r == 0)
@@ -273,9 +273,9 @@ namespace System.IO
private long GetLengthInternal()
{
- Interop.mincore.FILE_STANDARD_INFO info = new Interop.mincore.FILE_STANDARD_INFO();
+ Interop.Kernel32.FILE_STANDARD_INFO info = new Interop.Kernel32.FILE_STANDARD_INFO();
- if (!Interop.mincore.GetFileInformationByHandleEx(_fileHandle, Interop.mincore.FILE_INFO_BY_HANDLE_CLASS.FileStandardInfo, out info, (uint)Marshal.SizeOf<Interop.mincore.FILE_STANDARD_INFO>()))
+ if (!Interop.Kernel32.GetFileInformationByHandleEx(_fileHandle, Interop.Kernel32.FILE_INFO_BY_HANDLE_CLASS.FileStandardInfo, out info, (uint)Marshal.SizeOf<Interop.Kernel32.FILE_STANDARD_INFO>()))
throw Win32Marshal.GetExceptionForLastWin32Error();
long len = info.EndOfFile;
// If we're writing near the end of the file, we must include our
@@ -334,7 +334,7 @@ namespace System.IO
private void FlushOSBuffer()
{
- if (!Interop.mincore.FlushFileBuffers(_fileHandle))
+ if (!Interop.Kernel32.FlushFileBuffers(_fileHandle))
{
throw Win32Marshal.GetExceptionForLastWin32Error();
}
@@ -426,10 +426,10 @@ namespace System.IO
VerifyOSHandlePosition();
if (_filePosition != value)
SeekCore(value, SeekOrigin.Begin);
- if (!Interop.mincore.SetEndOfFile(_fileHandle))
+ if (!Interop.Kernel32.SetEndOfFile(_fileHandle))
{
int errorCode = Marshal.GetLastWin32Error();
- if (errorCode == Interop.mincore.Errors.ERROR_INVALID_PARAMETER)
+ if (errorCode == Interop.Errors.ERROR_INVALID_PARAMETER)
throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_FileLengthTooBig);
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
}
@@ -658,7 +658,7 @@ namespace System.IO
Debug.Assert(origin >= SeekOrigin.Begin && origin <= SeekOrigin.End, "origin>=SeekOrigin.Begin && origin<=SeekOrigin.End");
long ret = 0;
- if (!Interop.mincore.SetFilePointerEx(_fileHandle, offset, out ret, (uint)origin))
+ if (!Interop.Kernel32.SetFilePointerEx(_fileHandle, offset, out ret, (uint)origin))
{
int errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid();
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
@@ -1277,12 +1277,12 @@ namespace System.IO
int r = 0;
int numBytesRead = 0;
- fixed (byte* p = bytes)
+ fixed (byte* p = &bytes[0])
{
if (_useAsyncIO)
- r = Interop.mincore.ReadFile(handle, p + offset, count, IntPtr.Zero, overlapped);
+ r = Interop.Kernel32.ReadFile(handle, p + offset, count, IntPtr.Zero, overlapped);
else
- r = Interop.mincore.ReadFile(handle, p + offset, count, out numBytesRead, IntPtr.Zero);
+ r = Interop.Kernel32.ReadFile(handle, p + offset, count, out numBytesRead, IntPtr.Zero);
}
if (r == 0)
@@ -1322,12 +1322,12 @@ namespace System.IO
int numBytesWritten = 0;
int r = 0;
- fixed (byte* p = bytes)
+ fixed (byte* p = &bytes[0])
{
if (_useAsyncIO)
- r = Interop.mincore.WriteFile(handle, p + offset, count, IntPtr.Zero, overlapped);
+ r = Interop.Kernel32.WriteFile(handle, p + offset, count, IntPtr.Zero, overlapped);
else
- r = Interop.mincore.WriteFile(handle, p + offset, count, out numBytesWritten, IntPtr.Zero);
+ r = Interop.Kernel32.WriteFile(handle, p + offset, count, out numBytesWritten, IntPtr.Zero);
}
if (r == 0)
@@ -1363,7 +1363,7 @@ namespace System.IO
// Note that _parent.Dispose doesn't throw so we don't need to special case.
// SetHandleAsInvalid only sets _closed field to true (without
// actually closing handle) so we don't need to call that as well.
- if (errorCode == Interop.mincore.Errors.ERROR_INVALID_HANDLE)
+ if (errorCode == Interop.Errors.ERROR_INVALID_HANDLE)
{
_fileHandle.Dispose();
@@ -1473,7 +1473,7 @@ namespace System.IO
{
// Try to cancel the I/O. We ignore the return value, as cancellation is opportunistic and we
// don't want to fail the operation because we couldn't cancel it.
- Interop.mincore.CancelIoEx(innerAwaitable._fileStream._fileHandle, innerAwaitable._nativeOverlapped);
+ Interop.Kernel32.CancelIoEx(innerAwaitable._fileStream._fileHandle, innerAwaitable._nativeOverlapped);
}
}
}
@@ -1538,7 +1538,7 @@ namespace System.IO
case ERROR_HANDLE_EOF: // logically success with 0 bytes read (read at end of file)
Debug.Assert(readAwaitable._numBytes == 0, $"Expected 0 bytes read, got {readAwaitable._numBytes}");
break;
- case Interop.mincore.Errors.ERROR_OPERATION_ABORTED: // canceled
+ case Interop.Errors.ERROR_OPERATION_ABORTED: // canceled
throw new OperationCanceledException(cancellationToken.IsCancellationRequested ? cancellationToken : new CancellationToken(true));
default: // error
throw Win32Marshal.GetExceptionForWin32Error((int)readAwaitable._errorCode);
@@ -1748,7 +1748,7 @@ namespace System.IO
int lengthLow = unchecked((int)(length));
int lengthHigh = unchecked((int)(length >> 32));
- if (!Interop.mincore.LockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
+ if (!Interop.Kernel32.LockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
{
throw Win32Marshal.GetExceptionForLastWin32Error();
}
@@ -1761,7 +1761,7 @@ namespace System.IO
int lengthLow = unchecked((int)(length));
int lengthHigh = unchecked((int)(length >> 32));
- if (!Interop.mincore.UnlockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
+ if (!Interop.Kernel32.UnlockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
{
throw Win32Marshal.GetExceptionForLastWin32Error();
}
diff --git a/src/mscorlib/corefx/System/IO/FileStream.cs b/src/mscorlib/corefx/System/IO/FileStream.cs
index 398f5a6162..7db8518435 100644
--- a/src/mscorlib/corefx/System/IO/FileStream.cs
+++ b/src/mscorlib/corefx/System/IO/FileStream.cs
@@ -139,20 +139,6 @@ namespace System.IO
this(path, mode, access, share, bufferSize, useAsync ? FileOptions.Asynchronous : FileOptions.None)
{ }
- internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, string msgPath, bool bFromProxy)
- : this(path, mode, access, share, bufferSize, options, msgPath, bFromProxy, useLongPath: false)
- {
- }
-
- internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, string msgPath, bool bFromProxy, bool useLongPath)
- : this(path, mode, access, share, bufferSize, options)
- {
- // msgPath is the path that is handed back to untrusted code, CoreCLR is always full trust
- // bFromProxy is also related to asserting rights for limited trust and also can be ignored
- // useLongPath was used to get around the legacy MaxPath check, this is no longer applicable as everything supports long paths
- // checkHost is also related to limited trust scenarios
- }
-
public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
{
if (path == null)
@@ -225,24 +211,6 @@ namespace System.IO
return handle.IsAsync.HasValue ? handle.IsAsync.Value : false;
}
- // InternalOpen, InternalCreate, and InternalAppend:
- // Factory methods for FileStream used by File, FileInfo, and ReadLinesIterator
- // Specifies default access and sharing options for FileStreams created by those classes
- internal static FileStream InternalOpen(string path, int bufferSize = DefaultBufferSize, bool useAsync = DefaultIsAsync)
- {
- return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, useAsync);
- }
-
- internal static FileStream InternalCreate(string path, int bufferSize = DefaultBufferSize, bool useAsync = DefaultIsAsync)
- {
- return new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, bufferSize, useAsync);
- }
-
- internal static FileStream InternalAppend(string path, int bufferSize = DefaultBufferSize, bool useAsync = DefaultIsAsync)
- {
- return new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read, bufferSize, useAsync);
- }
-
[Obsolete("This property has been deprecated. Please use FileStream's SafeFileHandle property instead. http://go.microsoft.com/fwlink/?linkid=14202")]
public virtual IntPtr Handle { get { return SafeFileHandle.DangerousGetHandle(); } }
@@ -650,5 +618,67 @@ namespace System.IO
// on Dispose(false) call.
Dispose(false);
}
+
+ public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, AsyncCallback callback, object state)
+ {
+ if (array == null)
+ throw new ArgumentNullException(nameof(array));
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (numBytes < 0)
+ throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (array.Length - offset < numBytes)
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
+
+ if (IsClosed) throw new ObjectDisposedException(SR.ObjectDisposed_FileClosed);
+ if (!CanRead) throw new NotSupportedException(SR.NotSupported_UnreadableStream);
+
+ if (!IsAsync)
+ return base.BeginRead(array, offset, numBytes, callback, state);
+ else
+ return TaskToApm.Begin(ReadAsyncInternal(array, offset, numBytes, CancellationToken.None), callback, state);
+ }
+
+ public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback callback, object state)
+ {
+ if (array == null)
+ throw new ArgumentNullException(nameof(array));
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (numBytes < 0)
+ throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (array.Length - offset < numBytes)
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
+
+ if (IsClosed) throw new ObjectDisposedException(SR.ObjectDisposed_FileClosed);
+ if (!CanWrite) throw new NotSupportedException(SR.NotSupported_UnwritableStream);
+
+ if (!IsAsync)
+ return base.BeginWrite(array, offset, numBytes, callback, state);
+ else
+ return TaskToApm.Begin(WriteAsyncInternal(array, offset, numBytes, CancellationToken.None), callback, state);
+ }
+
+ public override int EndRead(IAsyncResult asyncResult)
+ {
+ if (asyncResult == null)
+ throw new ArgumentNullException(nameof(asyncResult));
+
+ if (!IsAsync)
+ return base.EndRead(asyncResult);
+ else
+ return TaskToApm.End<int>(asyncResult);
+ }
+
+ public override void EndWrite(IAsyncResult asyncResult)
+ {
+ if (asyncResult == null)
+ throw new ArgumentNullException(nameof(asyncResult));
+
+ if (!IsAsync)
+ base.EndWrite(asyncResult);
+ else
+ TaskToApm.End(asyncResult);
+ }
}
}
diff --git a/src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs b/src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs
index 532dbb0615..159e416e63 100644
--- a/src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs
+++ b/src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs
@@ -178,7 +178,7 @@ namespace System.IO
if (result == ResultError)
{
int errorCode = unchecked((int)(packedResult & uint.MaxValue));
- if (errorCode == Interop.mincore.Errors.ERROR_OPERATION_ABORTED)
+ if (errorCode == Interop.Errors.ERROR_OPERATION_ABORTED)
{
TrySetCanceled(_cancellationToken.IsCancellationRequested ? _cancellationToken : new CancellationToken(true));
}
@@ -204,13 +204,13 @@ namespace System.IO
// If the handle is still valid, attempt to cancel the IO
if (!completionSource._stream._fileHandle.IsInvalid &&
- !Interop.mincore.CancelIoEx(completionSource._stream._fileHandle, completionSource._overlapped))
+ !Interop.Kernel32.CancelIoEx(completionSource._stream._fileHandle, completionSource._overlapped))
{
int errorCode = Marshal.GetLastWin32Error();
// ERROR_NOT_FOUND is returned if CancelIoEx cannot find the request to cancel.
// This probably means that the IO operation has completed.
- if (errorCode != Interop.mincore.Errors.ERROR_NOT_FOUND)
+ if (errorCode != Interop.Errors.ERROR_NOT_FOUND)
{
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
}
diff --git a/src/mscorlib/corefx/System/IO/Path.Unix.cs b/src/mscorlib/corefx/System/IO/Path.Unix.cs
index 2dd1907007..c566fa0066 100644
--- a/src/mscorlib/corefx/System/IO/Path.Unix.cs
+++ b/src/mscorlib/corefx/System/IO/Path.Unix.cs
@@ -10,16 +10,11 @@ namespace System.IO
{
public static partial class Path
{
- public static readonly char DirectorySeparatorChar = '/';
- public static readonly char VolumeSeparatorChar = '/';
- public static readonly char PathSeparator = ':';
-
- private const string DirectorySeparatorCharAsString = "/";
-
public static char[] GetInvalidFileNameChars() => new char[] { '\0', '/' };
- internal static readonly int MaxPath = Interop.Sys.MaxPath;
- private static readonly int MaxLongPath = MaxPath;
+ public static char[] GetInvalidPathChars() => new char[] { '\0' };
+
+ internal static int MaxPath => Interop.Sys.MaxPath;
private static readonly bool s_isMac = Interop.Sys.GetUnixName() == "OSX";
@@ -47,12 +42,12 @@ namespace System.IO
Debug.Assert(collapsedString.Length < path.Length || collapsedString.ToString() == path,
"Either we've removed characters, or the string should be unmodified from the input path.");
- if (collapsedString.Length > MaxPath)
+ if (collapsedString.Length > Interop.Sys.MaxPath)
{
throw new PathTooLongException(SR.IO_PathTooLong);
}
- string result = collapsedString.Length == 0 ? DirectorySeparatorCharAsString : collapsedString;
+ string result = collapsedString.Length == 0 ? PathInternal.DirectorySeparatorCharAsString : collapsedString;
return result;
}
@@ -125,15 +120,15 @@ namespace System.IO
}
}
- if (++componentCharCount > PathInternal.MaxComponentLength)
+ if (++componentCharCount > Interop.Sys.MaxName)
{
throw new PathTooLongException(SR.IO_PathTooLong);
}
// Normalize the directory separator if needed
- if (c != Path.DirectorySeparatorChar && c == Path.AltDirectorySeparatorChar)
+ if (c != PathInternal.DirectorySeparatorChar && c == PathInternal.AltDirectorySeparatorChar)
{
- c = Path.DirectorySeparatorChar;
+ c = PathInternal.DirectorySeparatorChar;
flippedSeparator = true;
}
@@ -169,7 +164,7 @@ namespace System.IO
return
string.IsNullOrEmpty(path) ? DefaultTempPath :
PathInternal.IsDirectorySeparator(path[path.Length - 1]) ? path :
- path + DirectorySeparatorChar;
+ path + PathInternal.DirectorySeparatorChar;
}
public static string GetTempFileName()
@@ -197,58 +192,23 @@ namespace System.IO
return false;
PathInternal.CheckInvalidPathChars(path);
- return path.Length > 0 && path[0] == DirectorySeparatorChar;
+ return path.Length > 0 && path[0] == PathInternal.DirectorySeparatorChar;
}
public static string GetPathRoot(string path)
{
if (path == null) return null;
- return IsPathRooted(path) ? DirectorySeparatorCharAsString : String.Empty;
+ return IsPathRooted(path) ? PathInternal.DirectorySeparatorCharAsString : String.Empty;
}
private static unsafe void GetCryptoRandomBytes(byte* bytes, int byteCount)
{
-#if FEATURE_CORECLR
// We want to avoid dependencies on the Crypto library when compiling in CoreCLR. This
// will use the existing PAL implementation.
byte[] buffer = new byte[KeyLength];
Microsoft.Win32.Win32Native.Random(bStrong: true, buffer: buffer, length: KeyLength);
Runtime.InteropServices.Marshal.Copy(buffer, 0, (IntPtr)bytes, KeyLength);
-#else
- if (s_isMac)
- {
- GetCryptoRandomBytesApple(bytes, byteCount);
- }
- else
- {
- GetCryptoRandomBytesOpenSsl(bytes, byteCount);
- }
-#endif
- }
-
-#if !FEATURE_CORECLR
- private static unsafe void GetCryptoRandomBytesApple(byte* bytes, int byteCount)
- {
- Debug.Assert(bytes != null);
- Debug.Assert(byteCount >= 0);
-
- if (Interop.CommonCrypto.CCRandomGenerateBytes(bytes, byteCount) != 0)
- {
- throw new InvalidOperationException(SR.InvalidOperation_Cryptography);
- }
- }
-
- private static unsafe void GetCryptoRandomBytesOpenSsl(byte* bytes, int byteCount)
- {
- Debug.Assert(bytes != null);
- Debug.Assert(byteCount >= 0);
-
- if (!Interop.Crypto.GetRandomBytes(bytes, byteCount))
- {
- throw new InvalidOperationException(SR.InvalidOperation_Cryptography);
- }
}
-#endif
/// <summary>Gets whether the system is case-sensitive.</summary>
internal static bool IsCaseSensitive { get { return !s_isMac; } }
diff --git a/src/mscorlib/corefx/System/IO/Path.Windows.cs b/src/mscorlib/corefx/System/IO/Path.Windows.cs
index b597efc54e..ce867efd2c 100644
--- a/src/mscorlib/corefx/System/IO/Path.Windows.cs
+++ b/src/mscorlib/corefx/System/IO/Path.Windows.cs
@@ -9,14 +9,8 @@ namespace System.IO
{
public static partial class Path
{
- public static readonly char DirectorySeparatorChar = '\\';
- public static readonly char VolumeSeparatorChar = ':';
- public static readonly char PathSeparator = ';';
-
- private const string DirectorySeparatorCharAsString = "\\";
-
public static char[] GetInvalidFileNameChars() => new char[]
- {
+ {
'\"', '<', '>', '|', '\0',
(char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,
(char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,
@@ -24,10 +18,18 @@ namespace System.IO
(char)31, ':', '*', '?', '\\', '/'
};
+ public static char[] GetInvalidPathChars() => new char[]
+ {
+ '|', '\0',
+ (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,
+ (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,
+ (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,
+ (char)31
+ };
+
// The max total path is 260, and the max individual component length is 255.
// For example, D:\<256 char file name> isn't legal, even though it's under 260 chars.
- internal static readonly int MaxPath = 260;
- internal static readonly int MaxLongPath = short.MaxValue;
+ internal const int MaxPath = 260;
// Expands the given path to a fully qualified path.
public static string GetFullPath(string path)
@@ -64,9 +66,9 @@ namespace System.IO
// Move past the colon
startIndex += 2;
- if ((path.Length > 0 && path[0] == VolumeSeparatorChar)
- || (path.Length >= startIndex && path[startIndex - 1] == VolumeSeparatorChar && !PathInternal.IsValidDriveChar(path[startIndex - 2]))
- || (path.Length > startIndex && path.IndexOf(VolumeSeparatorChar, startIndex) != -1))
+ if ((path.Length > 0 && path[0] == PathInternal.VolumeSeparatorChar)
+ || (path.Length >= startIndex && path[startIndex - 1] == PathInternal.VolumeSeparatorChar && !PathInternal.IsValidDriveChar(path[startIndex - 2]))
+ || (path.Length > startIndex && path.IndexOf(PathInternal.VolumeSeparatorChar, startIndex) != -1))
{
throw new NotSupportedException(SR.Argument_PathFormatNotSupported);
}
@@ -92,7 +94,7 @@ namespace System.IO
public static string GetTempPath()
{
StringBuilder sb = StringBuilderCache.Acquire(MaxPath);
- uint r = Interop.mincore.GetTempPathW(MaxPath, sb);
+ uint r = Interop.Kernel32.GetTempPathW(MaxPath, sb);
if (r == 0)
throw Win32Marshal.GetExceptionForLastWin32Error();
return GetFullPath(StringBuilderCache.GetStringAndRelease(sb));
@@ -105,7 +107,7 @@ namespace System.IO
string path = GetTempPath();
StringBuilder sb = StringBuilderCache.Acquire(MaxPath);
- uint r = Interop.mincore.GetTempFileNameW(path, "tmp", 0, sb);
+ uint r = Interop.Kernel32.GetTempFileNameW(path, "tmp", 0, sb);
if (r == 0)
throw Win32Marshal.GetExceptionForLastWin32Error();
return StringBuilderCache.GetStringAndRelease(sb);
@@ -121,7 +123,7 @@ namespace System.IO
int length = path.Length;
if ((length >= 1 && PathInternal.IsDirectorySeparator(path[0])) ||
- (length >= 2 && path[1] == VolumeSeparatorChar))
+ (length >= 2 && path[1] == PathInternal.VolumeSeparatorChar))
return true;
}
return false;
diff --git a/src/mscorlib/corefx/System/IO/Path.cs b/src/mscorlib/corefx/System/IO/Path.cs
index 3b1ba6b07d..77b213968b 100644
--- a/src/mscorlib/corefx/System/IO/Path.cs
+++ b/src/mscorlib/corefx/System/IO/Path.cs
@@ -13,10 +13,12 @@ namespace System.IO
// but they will handle most string operations.
public static partial class Path
{
- // Platform specific alternate directory separator character.
- // There is only one directory separator char on Unix, which is the same
- // as the alternate separator on Windows, so same definition is used for both.
- public static readonly char AltDirectorySeparatorChar = '/';
+ // Public static readonly variant of the separators. The Path implementation itself is using
+ // internal const variant of the separators for better performance.
+ public static readonly char DirectorySeparatorChar = PathInternal.DirectorySeparatorChar;
+ public static readonly char AltDirectorySeparatorChar = PathInternal.AltDirectorySeparatorChar;
+ public static readonly char VolumeSeparatorChar = PathInternal.VolumeSeparatorChar;
+ public static readonly char PathSeparator = PathInternal.PathSeparator;
// For generating random file names
// 8 random bytes provides 12 chars in our encoding for the 8.3 name.
@@ -90,11 +92,6 @@ namespace System.IO
return null;
}
- public static char[] GetInvalidPathChars()
- {
- return PathInternal.GetInvalidPathChars();
- }
-
// Returns the extension of the given path. The returned value includes the
// period (".") character of the extension except when you have a terminal period when you get string.Empty, such as ".exe" or
// ".cpp". The returned value is null if the given path is
@@ -290,7 +287,7 @@ namespace System.IO
char ch = finalPath[finalPath.Length - 1];
if (!PathInternal.IsDirectoryOrVolumeSeparator(ch))
{
- finalPath.Append(DirectorySeparatorChar);
+ finalPath.Append(PathInternal.DirectorySeparatorChar);
}
finalPath.Append(paths[i]);
@@ -314,7 +311,7 @@ namespace System.IO
char ch = path1[path1.Length - 1];
return PathInternal.IsDirectoryOrVolumeSeparator(ch) ?
path1 + path2 :
- path1 + DirectorySeparatorCharAsString + path2;
+ path1 + PathInternal.DirectorySeparatorCharAsString + path2;
}
private static string CombineNoChecks(string path1, string path2, string path3)
@@ -340,11 +337,11 @@ namespace System.IO
}
else if (hasSep1)
{
- return path1 + path2 + DirectorySeparatorCharAsString + path3;
+ return path1 + path2 + PathInternal.DirectorySeparatorCharAsString + path3;
}
else if (hasSep2)
{
- return path1 + DirectorySeparatorCharAsString + path2 + path3;
+ return path1 + PathInternal.DirectorySeparatorCharAsString + path2 + path3;
}
else
{
@@ -352,9 +349,9 @@ namespace System.IO
// a params string[]. Instead, try to use a cached StringBuilder.
StringBuilder sb = StringBuilderCache.Acquire(path1.Length + path2.Length + path3.Length + 2);
sb.Append(path1)
- .Append(DirectorySeparatorChar)
+ .Append(PathInternal.DirectorySeparatorChar)
.Append(path2)
- .Append(DirectorySeparatorChar)
+ .Append(PathInternal.DirectorySeparatorChar)
.Append(path3);
return StringBuilderCache.GetStringAndRelease(sb);
}
@@ -396,19 +393,19 @@ namespace System.IO
sb.Append(path1);
if (!hasSep1)
{
- sb.Append(DirectorySeparatorChar);
+ sb.Append(PathInternal.DirectorySeparatorChar);
}
sb.Append(path2);
if (!hasSep2)
{
- sb.Append(DirectorySeparatorChar);
+ sb.Append(PathInternal.DirectorySeparatorChar);
}
sb.Append(path3);
if (!hasSep3)
{
- sb.Append(DirectorySeparatorChar);
+ sb.Append(PathInternal.DirectorySeparatorChar);
}
sb.Append(path4);
diff --git a/src/mscorlib/corefx/System/IO/PathHelper.Windows.cs b/src/mscorlib/corefx/System/IO/PathHelper.Windows.cs
index 4c2cdff45e..e2ead93185 100644
--- a/src/mscorlib/corefx/System/IO/PathHelper.Windows.cs
+++ b/src/mscorlib/corefx/System/IO/PathHelper.Windows.cs
@@ -11,7 +11,7 @@ namespace System.IO
/// <summary>
/// Wrapper to help with path normalization.
/// </summary>
- unsafe internal class PathHelper
+ internal class PathHelper
{
// Can't be over 8.3 and be a short name
private const int MaxShortName = 12;
@@ -19,9 +19,6 @@ namespace System.IO
private const char LastAnsi = (char)255;
private const char Delete = (char)127;
- [ThreadStatic]
- private static StringBuffer t_fullPathBuffer;
-
/// <summary>
/// Normalize the given path.
/// </summary>
@@ -44,10 +41,11 @@ namespace System.IO
internal static string Normalize(string path, bool checkInvalidCharacters, bool expandShortPaths)
{
// Get the full path
- StringBuffer fullPath = t_fullPathBuffer ?? (t_fullPathBuffer = new StringBuffer(PathInternal.MaxShortPath));
+ StringBuffer fullPath = new StringBuffer(PathInternal.MaxShortPath);
+
try
{
- GetFullPathName(path, fullPath);
+ GetFullPathName(path, ref fullPath);
// Trim whitespace off the end of the string. Win32 normalization trims only U+0020.
fullPath.TrimEnd(PathInternal.s_trimEndChars);
@@ -82,17 +80,16 @@ namespace System.IO
// path that contains UNC or to see if the path was doing something like \\.\GLOBALROOT\Device\Mup\,
// \\.\GLOBAL\UNC\, \\.\GLOBALROOT\GLOBAL??\UNC\, etc.
bool specialPath = fullPath.Length > 1 && fullPath[0] == '\\' && fullPath[1] == '\\';
- bool isDevice = PathInternal.IsDevice(fullPath);
+ bool isDevice = PathInternal.IsDevice(ref fullPath);
bool possibleBadUnc = specialPath && !isDevice;
- uint index = specialPath ? 2u : 0;
- uint lastSeparator = specialPath ? 1u : 0;
- uint segmentLength;
- char* start = fullPath.CharPointer;
+ int index = specialPath ? 2 : 0;
+ int lastSeparator = specialPath ? 1 : 0;
+ int segmentLength;
char current;
while (index < fullPath.Length)
{
- current = start[index];
+ current = fullPath[index];
// Try to skip deeper analysis. '?' and higher are valid/ignorable except for '\', '|', and '~'
if (current < '?' || current == '\\' || current == '|' || current == '~')
@@ -111,7 +108,7 @@ namespace System.IO
break;
case '\\':
segmentLength = index - lastSeparator - 1;
- if (segmentLength > (uint)PathInternal.MaxComponentLength)
+ if (segmentLength > PathInternal.MaxComponentLength)
throw new PathTooLongException(SR.IO_PathTooLong + fullPath.ToString());
lastSeparator = index;
@@ -151,7 +148,7 @@ namespace System.IO
throw new ArgumentException(SR.Arg_PathIllegalUNC);
segmentLength = fullPath.Length - lastSeparator - 1;
- if (segmentLength > (uint)PathInternal.MaxComponentLength)
+ if (segmentLength > PathInternal.MaxComponentLength)
throw new PathTooLongException(SR.IO_PathTooLong);
if (foundTilde && segmentLength <= MaxShortName)
@@ -161,11 +158,11 @@ namespace System.IO
// this is how we've always done this. This expansion is costly so we'll continue to let other short paths slide.
if (expandShortPaths && possibleShortPath)
{
- return TryExpandShortFileName(fullPath, originalPath: path);
+ return TryExpandShortFileName(ref fullPath, originalPath: path);
}
else
{
- if (fullPath.Length == (uint)path.Length && fullPath.StartsWith(path))
+ if (fullPath.Length == path.Length && fullPath.StartsWith(path))
{
// If we have the exact same string we were passed in, don't bother to allocate another string from the StringBuilder.
return path;
@@ -184,12 +181,12 @@ namespace System.IO
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static bool IsDosUnc(StringBuffer buffer)
+ private static bool IsDosUnc(ref StringBuffer buffer)
{
- return !PathInternal.IsDevice(buffer) && buffer.Length > 1 && buffer[0] == '\\' && buffer[1] == '\\';
+ return !PathInternal.IsDevice(ref buffer) && buffer.Length > 1 && buffer[0] == '\\' && buffer[1] == '\\';
}
- private static void GetFullPathName(string path, StringBuffer fullPath)
+ private static unsafe void GetFullPathName(string path, ref StringBuffer fullPath)
{
// If the string starts with an extended prefix we would need to remove it from the path before we call GetFullPathName as
// it doesn't root extended paths correctly. We don't currently resolve extended paths, so we'll just assert here.
@@ -201,10 +198,10 @@ namespace System.IO
fixed (char* pathStart = path)
{
uint result = 0;
- while ((result = Interop.mincore.GetFullPathNameW(pathStart + startIndex, fullPath.CharCapacity, fullPath.GetHandle(), IntPtr.Zero)) > fullPath.CharCapacity)
+ while ((result = Interop.Kernel32.GetFullPathNameW(pathStart + startIndex, (uint)fullPath.Capacity, fullPath.UnderlyingArray, IntPtr.Zero)) > fullPath.Capacity)
{
- // Reported size (which does not include the null) is greater than the buffer size. Increase the capacity.
- fullPath.EnsureCharCapacity(result);
+ // Reported size is greater than the buffer size. Increase the capacity.
+ fullPath.EnsureCapacity(checked((int)result));
}
if (result == 0)
@@ -212,23 +209,23 @@ namespace System.IO
// Failure, get the error and throw
int errorCode = Marshal.GetLastWin32Error();
if (errorCode == 0)
- errorCode = Interop.mincore.Errors.ERROR_BAD_PATHNAME;
+ errorCode = Interop.Errors.ERROR_BAD_PATHNAME;
throw Win32Marshal.GetExceptionForWin32Error(errorCode, path);
}
- fullPath.Length = result;
+ fullPath.Length = checked((int)result);
}
}
- private static uint GetInputBuffer(StringBuffer content, bool isDosUnc, out StringBuffer buffer)
+ private static int GetInputBuffer(ref StringBuffer content, bool isDosUnc, ref StringBuffer buffer)
{
- uint length = content.Length;
+ int length = content.Length;
length += isDosUnc
- ? (uint)PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength
+ ? PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength
: PathInternal.DevicePrefixLength;
- buffer = new StringBuffer(length);
+ buffer.EnsureCapacity(length + 1);
if (isDosUnc)
{
@@ -238,28 +235,28 @@ namespace System.IO
// Copy the source buffer over after the existing UNC prefix
content.CopyTo(
bufferIndex: PathInternal.UncPrefixLength,
- destination: buffer,
+ destination: ref buffer,
destinationIndex: PathInternal.UncExtendedPrefixLength,
count: content.Length - PathInternal.UncPrefixLength);
// Return the prefix difference
- return (uint)PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength;
+ return PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength;
}
else
{
- uint prefixSize = (uint)PathInternal.ExtendedPathPrefix.Length;
+ int prefixSize = PathInternal.ExtendedPathPrefix.Length;
buffer.CopyFrom(bufferIndex: 0, source: PathInternal.ExtendedPathPrefix);
- content.CopyTo(bufferIndex: 0, destination: buffer, destinationIndex: prefixSize, count: content.Length);
+ content.CopyTo(bufferIndex: 0, destination: ref buffer, destinationIndex: prefixSize, count: content.Length);
return prefixSize;
}
}
- private static string TryExpandShortFileName(StringBuffer outputBuffer, string originalPath)
+ private static string TryExpandShortFileName(ref StringBuffer outputBuffer, string originalPath)
{
// We guarantee we'll expand short names for paths that only partially exist. As such, we need to find the part of the path that actually does exist. To
// avoid allocating like crazy we'll create only one input array and modify the contents with embedded nulls.
- Debug.Assert(!PathInternal.IsPartiallyQualified(outputBuffer), "should have resolved by now");
+ Debug.Assert(!PathInternal.IsPartiallyQualified(ref outputBuffer), "should have resolved by now");
// We'll have one of a few cases by now (the normalized path will have already:
//
@@ -271,119 +268,131 @@ namespace System.IO
//
// Note that we will never get \??\ here as GetFullPathName() does not recognize \??\ and will return it as C:\??\ (or whatever the current drive is).
- uint rootLength = PathInternal.GetRootLength(outputBuffer);
- bool isDevice = PathInternal.IsDevice(outputBuffer);
+ int rootLength = PathInternal.GetRootLength(ref outputBuffer);
+ bool isDevice = PathInternal.IsDevice(ref outputBuffer);
- StringBuffer inputBuffer = null;
- bool isDosUnc = false;
- uint rootDifference = 0;
- bool wasDotDevice = false;
-
- // Add the extended prefix before expanding to allow growth over MAX_PATH
- if (isDevice)
+ StringBuffer inputBuffer = new StringBuffer(0);
+ try
{
- // We have one of the following (\\?\ or \\.\)
- inputBuffer = new StringBuffer();
- inputBuffer.Append(outputBuffer);
+ bool isDosUnc = false;
+ int rootDifference = 0;
+ bool wasDotDevice = false;
- if (outputBuffer[2] == '.')
+ // Add the extended prefix before expanding to allow growth over MAX_PATH
+ if (isDevice)
{
- wasDotDevice = true;
- inputBuffer[2] = '?';
+ // We have one of the following (\\?\ or \\.\)
+ inputBuffer.Append(ref outputBuffer);
+
+ if (outputBuffer[2] == '.')
+ {
+ wasDotDevice = true;
+ inputBuffer[2] = '?';
+ }
+ }
+ else
+ {
+ isDosUnc = IsDosUnc(ref outputBuffer);
+ rootDifference = GetInputBuffer(ref outputBuffer, isDosUnc, ref inputBuffer);
}
- }
- else
- {
- isDosUnc = IsDosUnc(outputBuffer);
- rootDifference = GetInputBuffer(outputBuffer, isDosUnc, out inputBuffer);
- }
- rootLength += rootDifference;
- uint inputLength = inputBuffer.Length;
+ rootLength += rootDifference;
+ int inputLength = inputBuffer.Length;
- bool success = false;
- uint foundIndex = inputBuffer.Length - 1;
+ bool success = false;
+ int foundIndex = inputBuffer.Length - 1;
- while (!success)
- {
- uint result = Interop.mincore.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity);
+ while (!success)
+ {
+ uint result = Interop.Kernel32.GetLongPathNameW(inputBuffer.UnderlyingArray, outputBuffer.UnderlyingArray, (uint)outputBuffer.Capacity);
- // Replace any temporary null we added
- if (inputBuffer[foundIndex] == '\0') inputBuffer[foundIndex] = '\\';
+ // Replace any temporary null we added
+ if (inputBuffer[foundIndex] == '\0') inputBuffer[foundIndex] = '\\';
- if (result == 0)
- {
- // Look to see if we couldn't find the file
- int error = Marshal.GetLastWin32Error();
- if (error != Interop.mincore.Errors.ERROR_FILE_NOT_FOUND && error != Interop.mincore.Errors.ERROR_PATH_NOT_FOUND)
+ if (result == 0)
{
- // Some other failure, give up
- break;
- }
+ // Look to see if we couldn't find the file
+ int error = Marshal.GetLastWin32Error();
+ if (error != Interop.Errors.ERROR_FILE_NOT_FOUND && error != Interop.Errors.ERROR_PATH_NOT_FOUND)
+ {
+ // Some other failure, give up
+ break;
+ }
- // We couldn't find the path at the given index, start looking further back in the string.
- foundIndex--;
+ // We couldn't find the path at the given index, start looking further back in the string.
+ foundIndex--;
- for (; foundIndex > rootLength && inputBuffer[foundIndex] != '\\'; foundIndex--) ;
- if (foundIndex == rootLength)
+ for (; foundIndex > rootLength && inputBuffer[foundIndex] != '\\'; foundIndex--) ;
+ if (foundIndex == rootLength)
+ {
+ // Can't trim the path back any further
+ break;
+ }
+ else
+ {
+ // Temporarily set a null in the string to get Windows to look further up the path
+ inputBuffer[foundIndex] = '\0';
+ }
+ }
+ else if (result > outputBuffer.Capacity)
{
- // Can't trim the path back any further
- break;
+ // Not enough space. The result count for this API does not include the null terminator.
+ outputBuffer.EnsureCapacity(checked((int)result));
+ result = Interop.Kernel32.GetLongPathNameW(inputBuffer.UnderlyingArray, outputBuffer.UnderlyingArray, (uint)outputBuffer.Capacity);
}
else
{
- // Temporarily set a null in the string to get Windows to look further up the path
- inputBuffer[foundIndex] = '\0';
+ // Found the path
+ success = true;
+ outputBuffer.Length = checked((int)result);
+ if (foundIndex < inputLength - 1)
+ {
+ // It was a partial find, put the non-existent part of the path back
+ outputBuffer.Append(ref inputBuffer, foundIndex, inputBuffer.Length - foundIndex);
+ }
}
}
- else if (result > outputBuffer.CharCapacity)
+
+ // Strip out the prefix and return the string
+ ref StringBuffer bufferToUse = ref Choose(success, ref outputBuffer, ref inputBuffer);
+
+ // Switch back from \\?\ to \\.\ if necessary
+ if (wasDotDevice)
+ bufferToUse[2] = '.';
+
+ string returnValue = null;
+
+ int newLength = (int)(bufferToUse.Length - rootDifference);
+ if (isDosUnc)
{
- // Not enough space. The result count for this API does not include the null terminator.
- outputBuffer.EnsureCharCapacity(result);
- result = Interop.mincore.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity);
+ // Need to go from \\?\UNC\ to \\?\UN\\
+ bufferToUse[PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength] = '\\';
+ }
+
+ // We now need to strip out any added characters at the front of the string
+ if (bufferToUse.SubstringEquals(originalPath, rootDifference, newLength))
+ {
+ // Use the original path to avoid allocating
+ returnValue = originalPath;
}
else
{
- // Found the path
- success = true;
- outputBuffer.Length = result;
- if (foundIndex < inputLength - 1)
- {
- // It was a partial find, put the non-existent part of the path back
- outputBuffer.Append(inputBuffer, foundIndex, inputBuffer.Length - foundIndex);
- }
+ returnValue = bufferToUse.Substring(rootDifference, newLength);
}
- }
- // Strip out the prefix and return the string
- StringBuffer bufferToUse = success ? outputBuffer : inputBuffer;
-
- // Switch back from \\?\ to \\.\ if necessary
- if (wasDotDevice)
- bufferToUse[2] = '.';
-
- string returnValue = null;
-
- int newLength = (int)(bufferToUse.Length - rootDifference);
- if (isDosUnc)
- {
- // Need to go from \\?\UNC\ to \\?\UN\\
- bufferToUse[PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength] = '\\';
- }
-
- // We now need to strip out any added characters at the front of the string
- if (bufferToUse.SubstringEquals(originalPath, rootDifference, newLength))
- {
- // Use the original path to avoid allocating
- returnValue = originalPath;
+ return returnValue;
}
- else
+ finally
{
- returnValue = bufferToUse.Substring(rootDifference, newLength);
+ inputBuffer.Free();
}
+ }
- inputBuffer.Dispose();
- return returnValue;
+ // Helper method to workaround lack of operator ? support for ref values
+ private static ref StringBuffer Choose(bool condition, ref StringBuffer s1, ref StringBuffer s2)
+ {
+ if (condition) return ref s1;
+ else return ref s2;
}
}
}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs b/src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs
deleted file mode 100644
index bea2df93b9..0000000000
--- a/src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics;
-
-namespace System.IO
-{
- /// <summary>Contains internal path helpers that are shared between many projects.</summary>
- internal static partial class PathInternal
- {
- private enum Tristate : byte
- {
- NotInitialized,
- True,
- False,
- }
-
- private static Tristate s_isCaseSensitive = Tristate.NotInitialized;
-
- /// <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;
- }
- }
-
- /// <summary>Gets whether the system is case-sensitive.</summary>
- internal static bool IsCaseSensitive
- {
- get
- {
- // This must be lazily initialized as there are dependencies on PathInternal's static constructor
- // being fully initialized. (GetIsCaseSensitive() calls GetFullPath() which needs to use PathInternal)
- if (s_isCaseSensitive == Tristate.NotInitialized)
- s_isCaseSensitive = GetIsCaseSensitive() ? Tristate.True : Tristate.False;
-
- return s_isCaseSensitive == Tristate.True;
- }
- }
-
- /// <summary>
- /// Determines whether the file system is case sensitive.
- /// </summary>
- /// <remarks>
- /// Ideally we'd use something like pathconf with _PC_CASE_SENSITIVE, but that is non-portable,
- /// not supported on Windows or Linux, etc. For now, this function creates a tmp file with capital letters
- /// and then tests for its existence with lower-case letters. This could return invalid results in corner
- /// cases where, for example, different file systems are mounted with differing sensitivities.
- /// </remarks>
- private static bool GetIsCaseSensitive()
- {
- try
- {
- string pathWithUpperCase = Path.Combine(Path.GetTempPath(), "CASESENSITIVETEST" + Guid.NewGuid().ToString("N"));
- using (new FileStream(pathWithUpperCase, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None, 0x1000, FileOptions.DeleteOnClose))
- {
- string lowerCased = pathWithUpperCase.ToLowerInvariant();
- return !File.Exists(lowerCased);
- }
- }
- catch (Exception exc)
- {
- // In case something goes terribly wrong, we don't want to fail just because
- // of a casing test, so we assume case-insensitive-but-preserving.
- Debug.Fail("Casing test failed: " + exc);
- return false;
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.Unix.cs b/src/mscorlib/corefx/System/IO/PathInternal.Unix.cs
index 6c39f99556..08dc1d0251 100644
--- a/src/mscorlib/corefx/System/IO/PathInternal.Unix.cs
+++ b/src/mscorlib/corefx/System/IO/PathInternal.Unix.cs
@@ -10,11 +10,15 @@ namespace System.IO
/// <summary>Contains internal path helpers that are shared between many projects.</summary>
internal static partial class PathInternal
{
+ internal const char DirectorySeparatorChar = '/';
+ internal const char AltDirectorySeparatorChar = '/';
+ internal const char VolumeSeparatorChar = '/';
+ internal const char PathSeparator = ':';
+
+ internal const string DirectorySeparatorCharAsString = "/";
+
// There is only one invalid path character in Unix
private const char InvalidPathChar = '\0';
- internal static char[] GetInvalidPathChars() => new char[] { InvalidPathChar };
-
- internal static readonly int MaxComponentLength = Interop.Sys.MaxName;
internal const string ParentDirectoryPrefix = @"../";
@@ -34,24 +38,8 @@ namespace System.IO
{
// The alternate directory separator char is the same as the directory separator,
// so we only need to check one.
- Debug.Assert(Path.DirectorySeparatorChar == Path.AltDirectorySeparatorChar);
- return c == Path.DirectorySeparatorChar;
- }
-
- /// <summary>
- /// Returns true if the path is too long
- /// </summary>
- internal static bool IsPathTooLong(string fullPath)
- {
- return fullPath.Length >= Interop.Sys.MaxPath;
- }
-
- /// <summary>
- /// Returns true if the directory is too long
- /// </summary>
- internal static bool IsDirectoryTooLong(string fullPath)
- {
- return fullPath.Length >= Interop.Sys.MaxPath;
+ Debug.Assert(DirectorySeparatorChar == AltDirectorySeparatorChar);
+ return c == DirectorySeparatorChar;
}
/// <summary>
@@ -101,15 +89,9 @@ namespace System.IO
{
// The directory separator, volume separator, and the alternate directory
// separator should be the same on Unix, so we only need to check one.
- Debug.Assert(Path.DirectorySeparatorChar == Path.AltDirectorySeparatorChar);
- Debug.Assert(Path.DirectorySeparatorChar == Path.VolumeSeparatorChar);
- return ch == Path.DirectorySeparatorChar;
- }
-
- internal static bool HasInvalidVolumeSeparator(string path)
- {
- // This is only ever true for Windows
- return false;
+ Debug.Assert(DirectorySeparatorChar == AltDirectorySeparatorChar);
+ Debug.Assert(DirectorySeparatorChar == VolumeSeparatorChar);
+ return ch == DirectorySeparatorChar;
}
internal static bool IsPartiallyQualified(string path)
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs b/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs
index fec2218844..84953df37b 100644
--- a/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs
+++ b/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs
@@ -13,7 +13,7 @@ namespace System.IO
/// <summary>
/// Returns true if the path uses the extended syntax (\\?\)
/// </summary>
- internal static bool IsExtended(StringBuffer path)
+ internal static bool IsExtended(ref StringBuffer path)
{
// While paths like "//?/C:/" will work, they're treated the same as "\\.\" paths.
// Skipping of normalization will *only* occur if back slashes ('\') are used.
@@ -27,20 +27,24 @@ namespace System.IO
/// <summary>
/// Gets the length of the root of the path (drive, share, etc.).
/// </summary>
- internal unsafe static uint GetRootLength(StringBuffer path)
+ internal unsafe static int GetRootLength(ref StringBuffer path)
{
if (path.Length == 0) return 0;
- return GetRootLength(path.CharPointer, path.Length);
+
+ fixed (char* value = path.UnderlyingArray)
+ {
+ return GetRootLength(value, path.Length);
+ }
}
/// <summary>
/// Returns true if the path uses any of the DOS device path syntaxes. ("\\.\", "\\?\", or "\??\")
/// </summary>
- internal static bool IsDevice(StringBuffer path)
+ internal static bool IsDevice(ref StringBuffer path)
{
// If the path begins with any two separators is will be recognized and normalized and prepped with
// "\??\" for internal usage correctly. "\??\" is recognized and handled, "/??/" is not.
- return IsExtended(path)
+ return IsExtended(ref path)
||
(
path.Length >= DevicePrefixLength
@@ -63,7 +67,7 @@ namespace System.IO
/// for C: (rooted, but relative). "C:\a" is rooted and not relative (the current directory
/// will not be used to modify the path).
/// </remarks>
- internal static bool IsPartiallyQualified(StringBuffer path)
+ internal static bool IsPartiallyQualified(ref StringBuffer path)
{
if (path.Length < 2)
{
@@ -82,7 +86,7 @@ namespace System.IO
// The only way to specify a fixed path that doesn't begin with two slashes
// is the drive, colon, slash format- i.e. C:\
return !((path.Length >= 3)
- && (path[1] == Path.VolumeSeparatorChar)
+ && (path[1] == VolumeSeparatorChar)
&& IsDirectorySeparator(path[2]));
}
}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.Windows.cs b/src/mscorlib/corefx/System/IO/PathInternal.Windows.cs
index bd7f1eae41..0ec9b30f99 100644
--- a/src/mscorlib/corefx/System/IO/PathInternal.Windows.cs
+++ b/src/mscorlib/corefx/System/IO/PathInternal.Windows.cs
@@ -40,6 +40,13 @@ namespace System.IO
// Local and Global MS-DOS Device Names
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff554302.aspx
+ internal const char DirectorySeparatorChar = '\\';
+ internal const char AltDirectorySeparatorChar = '/';
+ internal const char VolumeSeparatorChar = ':';
+ internal const char PathSeparator = ';';
+
+ internal const string DirectorySeparatorCharAsString = "\\";
+
internal const string ExtendedPathPrefix = @"\\?\";
internal const string UncPathPrefix = @"\\";
internal const string UncExtendedPrefixToInsert = @"?\UNC\";
@@ -58,22 +65,6 @@ namespace System.IO
internal const int UncExtendedPrefixLength = 8;
internal const int MaxComponentLength = 255;
- internal static char[] GetInvalidPathChars() => new char[]
- {
- '|', '\0',
- (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,
- (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,
- (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,
- (char)31
- };
-
- // [MS - FSA] 2.1.4.4 Algorithm for Determining if a FileName Is in an Expression
- // https://msdn.microsoft.com/en-us/library/ff469270.aspx
- private static readonly char[] s_wildcardChars =
- {
- '\"', '<', '>', '*', '?'
- };
-
/// <summary>
/// Returns true if the given character is a valid drive letter
/// </summary>
@@ -83,24 +74,6 @@ namespace System.IO
}
/// <summary>
- /// Returns true if the path is too long
- /// </summary>
- internal static bool IsPathTooLong(string fullPath)
- {
- // We'll never know precisely what will fail as paths get changed internally in Windows and
- // may grow to exceed MaxLongPath.
- return fullPath.Length >= MaxLongPath;
- }
-
- /// <summary>
- /// Returns true if the directory is too long
- /// </summary>
- internal static bool IsDirectoryTooLong(string fullPath)
- {
- return IsPathTooLong(fullPath);
- }
-
- /// <summary>
/// Adds the extended path prefix (\\?\) if not already a device path, IF the path is not relative,
/// AND the path is more than 259 characters. (> MAX_PATH + null)
/// </summary>
@@ -193,10 +166,12 @@ namespace System.IO
for (int i = 0; i < path.Length; i++)
{
char c = path[i];
-
- if (c <= '\u001f' || c == '|')
+ if (c <= '|') // fast path for common case - '|' is highest illegal character
{
- return true;
+ if (c <= '\u001f' || c == '|')
+ {
+ return true;
+ }
}
}
@@ -206,13 +181,24 @@ namespace System.IO
/// <summary>
/// Check for known wildcard characters. '*' and '?' are the most common ones.
/// </summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal unsafe static bool HasWildCardCharacters(string path)
+ internal static bool HasWildCardCharacters(string path)
{
// Question mark is part of dos device syntax so we have to skip if we are
int startIndex = IsDevice(path) ? ExtendedPathPrefix.Length : 0;
- return path.IndexOfAny(s_wildcardChars, startIndex) >= 0;
+ // [MS - FSA] 2.1.4.4 Algorithm for Determining if a FileName Is in an Expression
+ // https://msdn.microsoft.com/en-us/library/ff469270.aspx
+ for (int i = startIndex; i < path.Length; i++)
+ {
+ char c = path[i];
+ if (c <= '?') // fast path for common case - '?' is highest wildcard character
+ {
+ if (c == '\"' || c == '<' || c == '>' || c == '*' || c == '?')
+ return true;
+ }
+ }
+
+ return false;
}
/// <summary>
@@ -222,15 +208,15 @@ namespace System.IO
{
fixed(char* value = path)
{
- return (int)GetRootLength(value, (uint)path.Length);
+ return GetRootLength(value, path.Length);
}
}
- private unsafe static uint GetRootLength(char* path, uint pathLength)
+ private unsafe static int GetRootLength(char* path, int pathLength)
{
- uint i = 0;
- uint volumeSeparatorLength = 2; // Length to the colon "C:"
- uint uncRootLength = 2; // Length to the start of the server name "\\"
+ int i = 0;
+ int volumeSeparatorLength = 2; // Length to the colon "C:"
+ int uncRootLength = 2; // Length to the start of the server name "\\"
bool extendedSyntax = StartsWithOrdinal(path, pathLength, ExtendedPathPrefix);
bool extendedUncSyntax = StartsWithOrdinal(path, pathLength, UncExtendedPathPrefix);
@@ -240,12 +226,12 @@ namespace System.IO
if (extendedUncSyntax)
{
// "\\" -> "\\?\UNC\"
- uncRootLength = (uint)UncExtendedPathPrefix.Length;
+ uncRootLength = UncExtendedPathPrefix.Length;
}
else
{
// "C:" -> "\\?\C:"
- volumeSeparatorLength += (uint)ExtendedPathPrefix.Length;
+ volumeSeparatorLength += ExtendedPathPrefix.Length;
}
}
@@ -263,7 +249,7 @@ namespace System.IO
while (i < pathLength && (!IsDirectorySeparator(path[i]) || --n > 0)) i++;
}
}
- else if (pathLength >= volumeSeparatorLength && path[volumeSeparatorLength - 1] == Path.VolumeSeparatorChar)
+ else if (pathLength >= volumeSeparatorLength && path[volumeSeparatorLength - 1] == VolumeSeparatorChar)
{
// Path is at least longer than where we expect a colon, and has a colon (\\?\A:, A:)
// If the colon is followed by a directory separator, move past it
@@ -273,9 +259,9 @@ namespace System.IO
return i;
}
- private unsafe static bool StartsWithOrdinal(char* source, uint sourceLength, string value)
+ private unsafe static bool StartsWithOrdinal(char* source, int sourceLength, string value)
{
- if (sourceLength < (uint)value.Length) return false;
+ if (sourceLength < value.Length) return false;
for (int i = 0; i < value.Length; i++)
{
if (value[i] != source[i]) return false;
@@ -314,7 +300,7 @@ namespace System.IO
// The only way to specify a fixed path that doesn't begin with two slashes
// is the drive, colon, slash format- i.e. C:\
return !((path.Length >= 3)
- && (path[1] == Path.VolumeSeparatorChar)
+ && (path[1] == VolumeSeparatorChar)
&& IsDirectorySeparator(path[2])
// To match old behavior we'll check the drive character for validity as the path is technically
// not qualified if you don't have a valid drive. "=:\" is the "=" file's default data stream.
@@ -350,7 +336,7 @@ namespace System.IO
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsDirectorySeparator(char c)
{
- return c == Path.DirectorySeparatorChar || c == Path.AltDirectorySeparatorChar;
+ return c == DirectorySeparatorChar || c == AltDirectorySeparatorChar;
}
/// <summary>
@@ -401,7 +387,7 @@ namespace System.IO
{
current = path[i];
if (IsDirectorySeparator(current)
- && (current != Path.DirectorySeparatorChar
+ && (current != DirectorySeparatorChar
// Check for sequential separators past the first position (we need to keep initial two for UNC/extended)
|| (i > 0 && i + 1 < path.Length && IsDirectorySeparator(path[i + 1]))))
{
@@ -418,7 +404,7 @@ namespace System.IO
if (IsDirectorySeparator(path[start]))
{
start++;
- builder.Append(Path.DirectorySeparatorChar);
+ builder.Append(DirectorySeparatorChar);
}
for (int i = start; i < path.Length; i++)
@@ -435,7 +421,7 @@ namespace System.IO
}
// Ensure it is the primary separator
- current = Path.DirectorySeparatorChar;
+ current = DirectorySeparatorChar;
}
builder.Append(current);
@@ -450,33 +436,7 @@ namespace System.IO
/// <param name="ch">The character to test.</param>
internal static bool IsDirectoryOrVolumeSeparator(char ch)
{
- return IsDirectorySeparator(ch) || Path.VolumeSeparatorChar == ch;
- }
-
- /// <summary>
- /// Validates volume separator only occurs as C: or \\?\C:. This logic is meant to filter out Alternate Data Streams.
- /// </summary>
- /// <returns>True if the path has an invalid volume separator.</returns>
- internal static bool HasInvalidVolumeSeparator(string path)
- {
- // Toss out paths with colons that aren't a valid drive specifier.
- // Cannot start with a colon and can only be of the form "C:" or "\\?\C:".
- // (Note that we used to explicitly check "http:" and "file:"- these are caught by this check now.)
-
- // We don't care about skipping starting space for extended paths. Assume no knowledge of extended paths if we're forcing old path behavior.
- int startIndex = IsExtended(path) ? ExtendedPathPrefix.Length : PathStartSkip(path);
-
- // If we start with a colon
- if ((path.Length > startIndex && path[startIndex] == Path.VolumeSeparatorChar)
- // Or have an invalid drive letter and colon
- || (path.Length >= startIndex + 2 && path[startIndex + 1] == Path.VolumeSeparatorChar && !IsValidDriveChar(path[startIndex]))
- // Or have any colons beyond the drive colon
- || (path.Length > startIndex + 2 && path.IndexOf(Path.VolumeSeparatorChar, startIndex + 2) != -1))
- {
- return true;
- }
-
- return false;
+ return IsDirectorySeparator(ch) || VolumeSeparatorChar == ch;
}
}
}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.cs b/src/mscorlib/corefx/System/IO/PathInternal.cs
index ee67680df5..6b4c3b2d30 100644
--- a/src/mscorlib/corefx/System/IO/PathInternal.cs
+++ b/src/mscorlib/corefx/System/IO/PathInternal.cs
@@ -40,64 +40,6 @@ namespace System.IO
if (HasIllegalCharacters(path))
throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
}
-
-
- /// <summary>
- /// Returns true if the given StringBuilder starts with the given value.
- /// </summary>
- /// <param name="value">The string to compare against the start of the StringBuilder.</param>
- internal static bool StartsWithOrdinal(this StringBuilder builder, string value)
- {
- if (value == null || builder.Length < value.Length)
- return false;
-
- for (int i = 0; i < value.Length; i++)
- {
- if (builder[i] != value[i]) return false;
- }
- return true;
- }
-
- /// <summary>
- /// Returns true if the given string starts with the given value.
- /// </summary>
- /// <param name="value">The string to compare against the start of the source string.</param>
- internal static bool StartsWithOrdinal(this string source, string value)
- {
- if (value == null || source.Length < value.Length)
- return false;
-
- return source.StartsWith(value, StringComparison.Ordinal);
- }
-
- /// <summary>
- /// Trims the specified characters from the end of the StringBuilder.
- /// </summary>
- internal static StringBuilder TrimEnd(this StringBuilder builder, params char[] trimChars)
- {
- if (trimChars == null || trimChars.Length == 0)
- return builder;
-
- int end = builder.Length - 1;
-
- for (; end >= 0; end--)
- {
- int i = 0;
- char ch = builder[end];
- for (; i < trimChars.Length; i++)
- {
- if (trimChars[i] == ch) break;
- }
- if (i == trimChars.Length)
- {
- // Not a trim char
- break;
- }
- }
-
- builder.Length = end + 1;
- return builder;
- }
/// <summary>
/// Returns the start index of the filename
diff --git a/src/mscorlib/corefx/System/IO/Win32Marshal.cs b/src/mscorlib/corefx/System/IO/Win32Marshal.cs
index b4dfa04468..ef76c27010 100644
--- a/src/mscorlib/corefx/System/IO/Win32Marshal.cs
+++ b/src/mscorlib/corefx/System/IO/Win32Marshal.cs
@@ -23,16 +23,6 @@ namespace System.IO
}
/// <summary>
- /// Converts, resetting it, the last Win32 error into a corresponding <see cref="Exception"/> object, optionally
- /// including the specified path in the error message.
- /// </summary>
- internal static Exception GetExceptionForLastWin32Error(string path)
- {
- int errorCode = Marshal.GetLastWin32Error();
- return GetExceptionForWin32Error(errorCode, path);
- }
-
- /// <summary>
/// Converts the specified Win32 error into a corresponding <see cref="Exception"/> object.
/// </summary>
internal static Exception GetExceptionForWin32Error(int errorCode)
@@ -48,49 +38,49 @@ namespace System.IO
{
switch (errorCode)
{
- case Interop.mincore.Errors.ERROR_FILE_NOT_FOUND:
+ case Interop.Errors.ERROR_FILE_NOT_FOUND:
if (path.Length == 0)
return new FileNotFoundException(SR.IO_FileNotFound);
else
return new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, path), path);
- case Interop.mincore.Errors.ERROR_PATH_NOT_FOUND:
+ case Interop.Errors.ERROR_PATH_NOT_FOUND:
if (path.Length == 0)
return new DirectoryNotFoundException(SR.IO_PathNotFound_NoPathName);
else
return new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, path));
- case Interop.mincore.Errors.ERROR_ACCESS_DENIED:
+ case Interop.Errors.ERROR_ACCESS_DENIED:
if (path.Length == 0)
return new UnauthorizedAccessException(SR.UnauthorizedAccess_IODenied_NoPathName);
else
return new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_IODenied_Path, path));
- case Interop.mincore.Errors.ERROR_ALREADY_EXISTS:
+ case Interop.Errors.ERROR_ALREADY_EXISTS:
if (path.Length == 0)
goto default;
return new IOException(SR.Format(SR.IO_AlreadyExists_Name, path), MakeHRFromErrorCode(errorCode));
- case Interop.mincore.Errors.ERROR_FILENAME_EXCED_RANGE:
+ case Interop.Errors.ERROR_FILENAME_EXCED_RANGE:
return new PathTooLongException(SR.IO_PathTooLong);
- case Interop.mincore.Errors.ERROR_INVALID_PARAMETER:
+ case Interop.Errors.ERROR_INVALID_PARAMETER:
return new IOException(GetMessage(errorCode), MakeHRFromErrorCode(errorCode));
- case Interop.mincore.Errors.ERROR_SHARING_VIOLATION:
+ case Interop.Errors.ERROR_SHARING_VIOLATION:
if (path.Length == 0)
return new IOException(SR.IO_SharingViolation_NoFileName, MakeHRFromErrorCode(errorCode));
else
return new IOException(SR.Format(SR.IO_SharingViolation_File, path), MakeHRFromErrorCode(errorCode));
- case Interop.mincore.Errors.ERROR_FILE_EXISTS:
+ case Interop.Errors.ERROR_FILE_EXISTS:
if (path.Length == 0)
goto default;
return new IOException(SR.Format(SR.IO_FileExists_Name, path), MakeHRFromErrorCode(errorCode));
- case Interop.mincore.Errors.ERROR_OPERATION_ABORTED:
+ case Interop.Errors.ERROR_OPERATION_ABORTED:
return new OperationCanceledException();
default:
@@ -109,26 +99,11 @@ namespace System.IO
}
/// <summary>
- /// Returns a Win32 error code for the specified HRESULT if it came from FACILITY_WIN32
- /// If not, returns the HRESULT unchanged
- /// </summary>
- internal static int TryMakeWin32ErrorCodeFromHR(int hr)
- {
- if ((0xFFFF0000 & hr) == 0x80070000)
- {
- // Win32 error, Win32Marshal.GetExceptionForWin32Error expects the Win32 format
- hr &= 0x0000FFFF;
- }
-
- return hr;
- }
-
- /// <summary>
/// Returns a string message for the specified Win32 error code.
/// </summary>
internal static string GetMessage(int errorCode)
{
- return Interop.mincore.GetMessage(errorCode);
+ return Interop.Kernel32.GetMessage(errorCode);
}
}
}
diff --git a/src/mscorlib/corefx/System/Runtime/InteropServices/NativeBuffer.cs b/src/mscorlib/corefx/System/Runtime/InteropServices/NativeBuffer.cs
deleted file mode 100644
index 875009aee2..0000000000
--- a/src/mscorlib/corefx/System/Runtime/InteropServices/NativeBuffer.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Runtime.CompilerServices;
-
-namespace System.Runtime.InteropServices
-{
- /// <summary>
- /// Wrapper for access to the native heap. Dispose to free the memory. Try to use with using statements.
- /// Does not allocate zero size buffers, and will free the existing native buffer if capacity is dropped to zero.
- ///
- /// NativeBuffer utilizes a cache of heap buffers.
- /// </summary>
- /// <remarks>
- /// Suggested use through P/Invoke: define DllImport arguments that take a byte buffer as SafeHandle.
- ///
- /// Using SafeHandle will ensure that the buffer will not get collected during a P/Invoke.
- /// (Notably AddRef and ReleaseRef will be called by the interop layer.)
- ///
- /// This class is not threadsafe, changing the capacity or disposing on multiple threads risks duplicate heap
- /// handles or worse.
- /// </remarks>
- internal class NativeBuffer : IDisposable
- {
- private readonly static SafeHeapHandleCache s_handleCache = new SafeHeapHandleCache();
- private readonly static SafeHandle s_emptyHandle = new EmptySafeHandle();
- private SafeHeapHandle _handle;
- private ulong _capacity;
-
- /// <summary>
- /// Create a buffer with at least the specified initial capacity in bytes.
- /// </summary>
- public NativeBuffer(ulong initialMinCapacity = 0)
- {
- EnsureByteCapacity(initialMinCapacity);
- }
-
- protected unsafe void* VoidPointer
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
- {
- return _handle == null ? null : _handle.DangerousGetHandle().ToPointer();
- }
- }
-
- protected unsafe byte* BytePointer
- {
- get
- {
- return (byte*)VoidPointer;
- }
- }
-
- /// <summary>
- /// Get the handle for the buffer.
- /// </summary>
- public SafeHandle GetHandle()
- {
- // Marshalling code will throw on null for SafeHandle
- return _handle ?? s_emptyHandle;
- }
-
- /// <summary>
- /// The capacity of the buffer in bytes.
- /// </summary>
- public ulong ByteCapacity
- {
- get { return _capacity; }
- }
-
- /// <summary>
- /// Ensure capacity in bytes is at least the given minimum.
- /// </summary>
- /// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if attempting to set <paramref name="nameof(minCapacity)"/> to a value that is larger than the maximum addressable memory.</exception>
- public void EnsureByteCapacity(ulong minCapacity)
- {
- if (_capacity < minCapacity)
- {
- Resize(minCapacity);
- _capacity = minCapacity;
- }
- }
-
- public unsafe byte this[ulong index]
- {
- get
- {
- if (index >= _capacity) throw new ArgumentOutOfRangeException();
- return BytePointer[index];
- }
- set
- {
- if (index >= _capacity) throw new ArgumentOutOfRangeException();
- BytePointer[index] = value;
- }
- }
-
- private unsafe void Resize(ulong byteLength)
- {
- if (byteLength == 0)
- {
- ReleaseHandle();
- return;
- }
-
- if (_handle == null)
- {
- _handle = s_handleCache.Acquire(byteLength);
- }
- else
- {
- _handle.Resize(byteLength);
- }
- }
-
- private void ReleaseHandle()
- {
- if (_handle != null)
- {
- s_handleCache.Release(_handle);
- _capacity = 0;
- _handle = null;
- }
- }
-
- /// <summary>
- /// Release the backing buffer
- /// </summary>
- public virtual void Free()
- {
- ReleaseHandle();
- }
-
- public void Dispose()
- {
- Free();
- }
-
- private sealed class EmptySafeHandle : SafeHandle
- {
- public EmptySafeHandle() : base(IntPtr.Zero, true) { }
-
- public override bool IsInvalid
- {
- get { return true; }
- }
-
- protected override bool ReleaseHandle()
- {
- return true;
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandle.cs b/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandle.cs
deleted file mode 100644
index 92b3d980db..0000000000
--- a/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandle.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.InteropServices
-{
- /// <summary>
- /// Handle for heap memory that allows tracking of capacity and reallocating.
- /// </summary>
- internal sealed class SafeHeapHandle : SafeBuffer
- {
- /// <summary>
- /// Allocate a buffer of the given size if requested.
- /// </summary>
- /// <param name="byteLength">Required size in bytes. Must be less than UInt32.MaxValue for 32 bit or UInt64.MaxValue for 64 bit.</param>
- /// <exception cref="OutOfMemoryException">Thrown if the requested memory size cannot be allocated.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if size is greater than the maximum memory size.</exception>
- public SafeHeapHandle(ulong byteLength) : base(ownsHandle: true)
- {
- Resize(byteLength);
- }
-
- public override bool IsInvalid
- {
- get { return handle == IntPtr.Zero; }
- }
-
- /// <summary>
- /// Resize the buffer to the given size if requested.
- /// </summary>
- /// <param name="byteLength">Required size in bytes. Must be less than UInt32.MaxValue for 32 bit or UInt64.MaxValue for 64 bit.</param>
- /// <exception cref="OutOfMemoryException">Thrown if the requested memory size cannot be allocated.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if size is greater than the maximum memory size.</exception>
- public void Resize(ulong byteLength)
- {
- if (IsClosed) throw new ObjectDisposedException(nameof(SafeHeapHandle));
-
- ulong originalLength = 0;
- if (handle == IntPtr.Zero)
- {
- handle = Marshal.AllocHGlobal((IntPtr)byteLength);
- }
- else
- {
- originalLength = ByteLength;
-
- // This may or may not be the same handle, may realloc in place. If the
- // handle changes Windows will deal with the old handle, trying to free it will
- // cause an error.
- handle = Marshal.ReAllocHGlobal(pv: handle, cb: (IntPtr)byteLength);
- }
-
- if (handle == IntPtr.Zero)
- {
- // Only real plausible answer
- throw new OutOfMemoryException();
- }
-
- if (byteLength > originalLength)
- {
- // Add pressure
- ulong addedBytes = byteLength - originalLength;
- if (addedBytes > long.MaxValue)
- {
- GC.AddMemoryPressure(long.MaxValue);
- GC.AddMemoryPressure((long)(addedBytes - long.MaxValue));
- }
- else
- {
- GC.AddMemoryPressure((long)addedBytes);
- }
- }
- else
- {
- // Shrank or did nothing, release pressure if needed
- RemoveMemoryPressure(originalLength - byteLength);
- }
-
- Initialize(byteLength);
- }
-
- private void RemoveMemoryPressure(ulong removedBytes)
- {
- if (removedBytes == 0) return;
-
- if (removedBytes > long.MaxValue)
- {
- GC.RemoveMemoryPressure(long.MaxValue);
- GC.RemoveMemoryPressure((long)(removedBytes - long.MaxValue));
- }
- else
- {
- GC.RemoveMemoryPressure((long)removedBytes);
- }
- }
-
- protected override bool ReleaseHandle()
- {
- if (handle != IntPtr.Zero)
- {
- RemoveMemoryPressure(ByteLength);
- Marshal.FreeHGlobal(handle);
- }
-
- handle = IntPtr.Zero;
- return true;
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs b/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs
deleted file mode 100644
index 725076ed66..0000000000
--- a/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Threading;
-
-namespace System.Runtime.InteropServices
-{
- /// <summary>
- /// Allows limited thread safe reuse of heap buffers to limit memory pressure.
- ///
- /// This cache does not ensure that multiple copies of handles are not released back into the cache.
- /// </summary>
- internal sealed class SafeHeapHandleCache : IDisposable
- {
- private readonly ulong _minSize;
- private readonly ulong _maxSize;
-
- // internal for testing
- internal readonly SafeHeapHandle[] _handleCache;
-
- /// <param name="minSize">Smallest buffer size to allocate in bytes.</param>
- /// <param name="maxSize">The largest buffer size to cache in bytes.</param>
- /// <param name="maxHandles">The maximum number of handles to cache.</param>
- public SafeHeapHandleCache(ulong minSize = 64, ulong maxSize = 1024 * 2, int maxHandles = 0)
- {
- _minSize = minSize;
- _maxSize = maxSize;
- _handleCache = new SafeHeapHandle[maxHandles > 0 ? maxHandles : Environment.ProcessorCount * 4];
- }
-
- /// <summary>
- /// Get a HeapHandle
- /// </summary>
- public SafeHeapHandle Acquire(ulong minSize = 0)
- {
- if (minSize < _minSize) minSize = _minSize;
-
- SafeHeapHandle handle = null;
-
- for (int i = 0; i < _handleCache.Length; i++)
- {
- handle = Interlocked.Exchange(ref _handleCache[i], null);
- if (handle != null) break;
- }
-
- if (handle != null)
- {
- // One possible future consideration is to attempt cycling through to
- // find one that might already have sufficient capacity
- if (handle.ByteLength < minSize)
- handle.Resize(minSize);
- }
- else
- {
- handle = new SafeHeapHandle(minSize);
- }
-
- return handle;
- }
-
- /// <summary>
- /// Give a HeapHandle back for potential reuse
- /// </summary>
- public void Release(SafeHeapHandle handle)
- {
- if (handle.ByteLength <= _maxSize)
- {
- for (int i = 0; i < _handleCache.Length; i++)
- {
- // Push the handles down, walking the last one off the end to keep
- // the top of the "stack" fresh
- handle = Interlocked.Exchange(ref _handleCache[i], handle);
- if (handle == null) return;
- }
- }
-
- handle.Dispose();
- }
-
- public void Dispose()
- {
- Dispose(disposing: true);
- }
-
- private void Dispose(bool disposing)
- {
- if (disposing && _handleCache != null)
- {
- foreach (SafeHeapHandle handle in _handleCache)
- {
- if (handle != null) handle.Dispose();
- }
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs b/src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs
index 29cef08b6c..fdd0b95590 100644
--- a/src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs
+++ b/src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs
@@ -2,69 +2,81 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Buffers;
+using System.Runtime.CompilerServices;
+
namespace System.Runtime.InteropServices
{
/// <summary>
- /// Native buffer that deals in char size increments. Dispose to free memory. Allows buffers larger
- /// than a maximum size string to enable working with very large string arrays. Always makes ordinal
- /// comparisons.
+ /// Buffer that deals in char size increments. Dispose to free memory. Always makes ordinal
+ /// comparisons. Not thread safe.
///
/// A more performant replacement for StringBuilder when performing native interop.
+ ///
+ /// "No copy" valuetype. Has to be passed as "ref".
+ ///
/// </summary>
/// <remarks>
/// Suggested use through P/Invoke: define DllImport arguments that take a character buffer as SafeHandle and pass StringBuffer.GetHandle().
/// </remarks>
- internal class StringBuffer : NativeBuffer
+ internal struct StringBuffer
{
- private uint _length;
+ private char[] _buffer;
+ private int _length;
/// <summary>
/// Instantiate the buffer with capacity for at least the specified number of characters. Capacity
/// includes the trailing null character.
/// </summary>
- public StringBuffer(uint initialCapacity = 0)
- : base(initialCapacity * (ulong)sizeof(char))
+ public StringBuffer(int initialCapacity)
{
+ _buffer = ArrayPool<char>.Shared.Rent(initialCapacity);
+ _length = 0;
}
/// <summary>
/// Get/set the character at the given index.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">Thrown if attempting to index outside of the buffer length.</exception>
- public unsafe char this[uint index]
+ public char this[int index]
{
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (index >= _length) throw new ArgumentOutOfRangeException(nameof(index));
- return CharPointer[index];
+ return _buffer[index];
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
if (index >= _length) throw new ArgumentOutOfRangeException(nameof(index));
- CharPointer[index] = value;
+ _buffer[index] = value;
}
}
/// <summary>
+ /// Underlying storage of the buffer. Used for interop.
+ /// </summary>
+ public char[] UnderlyingArray => _buffer;
+
+ /// <summary>
/// Character capacity of the buffer. Includes the count for the trailing null character.
/// </summary>
- public uint CharCapacity
- {
- get
- {
- ulong byteCapacity = ByteCapacity;
- ulong charCapacity = byteCapacity == 0 ? 0 : byteCapacity / sizeof(char);
- return charCapacity > uint.MaxValue ? uint.MaxValue : (uint)charCapacity;
- }
- }
+ public int Capacity => _buffer.Length;
/// <summary>
/// Ensure capacity in characters is at least the given minimum.
/// </summary>
/// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
- public void EnsureCharCapacity(uint minCapacity)
+ public void EnsureCapacity(int minCapacity)
{
- EnsureByteCapacity(minCapacity * (ulong)sizeof(char));
+ if (minCapacity > Capacity)
+ {
+ char[] oldBuffer = _buffer;
+ _buffer = ArrayPool<char>.Shared.Rent(minCapacity);
+ Array.Copy(oldBuffer, 0, _buffer, 0, oldBuffer.Length);
+ ArrayPool<char>.Shared.Return(oldBuffer);
+ }
}
/// <summary>
@@ -72,59 +84,32 @@ namespace System.Runtime.InteropServices
/// This is where the usable data ends.
/// </summary>
/// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if the set size in bytes is uint.MaxValue (as space is implicitly reserved for the trailing null).</exception>
- public unsafe uint Length
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if the set size in bytes is int.MaxValue (as space is implicitly reserved for the trailing null).</exception>
+ public int Length
{
get { return _length; }
set
{
- if (value == uint.MaxValue) throw new ArgumentOutOfRangeException(nameof(Length));
-
// Null terminate
- EnsureCharCapacity(value + 1);
- CharPointer[value] = '\0';
+ EnsureCapacity(checked(value + 1));
+ _buffer[value] = '\0';
_length = value;
}
}
/// <summary>
- /// For use when the native api null terminates but doesn't return a length.
- /// If no null is found, the length will not be changed.
- /// </summary>
- public unsafe void SetLengthToFirstNull()
- {
- char* buffer = CharPointer;
- uint capacity = CharCapacity;
- for (uint i = 0; i < capacity; i++)
- {
- if (buffer[i] == '\0')
- {
- _length = i;
- break;
- }
- }
- }
-
- internal unsafe char* CharPointer
- {
- get
- {
- return (char*)VoidPointer;
- }
- }
-
- /// <summary>
/// True if the buffer contains the given character.
/// </summary>
public unsafe bool Contains(char value)
{
- char* start = CharPointer;
- uint length = _length;
-
- for (uint i = 0; i < length; i++)
+ fixed (char* start = _buffer)
{
- if (*start++ == value) return true;
+ int length = _length;
+ for (int i = 0; i < length; i++)
+ {
+ if (start[i] == value) return true;
+ }
}
return false;
@@ -136,7 +121,7 @@ namespace System.Runtime.InteropServices
public bool StartsWith(string value)
{
if (value == null) throw new ArgumentNullException(nameof(value));
- if (_length < (uint)value.Length) return false;
+ if (_length < value.Length) return false;
return SubstringEquals(value, startIndex: 0, count: value.Length);
}
@@ -150,27 +135,28 @@ namespace System.Runtime.InteropServices
/// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
/// of the buffer's length.
/// </exception>
- public unsafe bool SubstringEquals(string value, uint startIndex = 0, int count = -1)
+ public unsafe bool SubstringEquals(string value, int startIndex = 0, int count = -1)
{
if (value == null) return false;
if (count < -1) throw new ArgumentOutOfRangeException(nameof(count));
if (startIndex > _length) throw new ArgumentOutOfRangeException(nameof(startIndex));
- uint realCount = count == -1 ? _length - startIndex : (uint)count;
+ int realCount = count == -1 ? _length - startIndex : (int)count;
if (checked(startIndex + realCount) > _length) throw new ArgumentOutOfRangeException(nameof(count));
int length = value.Length;
// Check the substring length against the input length
- if (realCount != (uint)length) return false;
+ if (realCount != length) return false;
fixed (char* valueStart = value)
+ fixed (char* bufferStart = _buffer)
{
- char* bufferStart = CharPointer + startIndex;
+ char* subStringStart = bufferStart + startIndex;
+
for (int i = 0; i < length; i++)
{
- // Note that indexing in this case generates faster code than trying to copy the pointer and increment it
- if (*bufferStart++ != valueStart[i]) return false;
+ if (subStringStart[i] != valueStart[i]) return false;
}
}
@@ -178,26 +164,6 @@ namespace System.Runtime.InteropServices
}
/// <summary>
- /// Append the given string.
- /// </summary>
- /// <param name="value">The string to append.</param>
- /// <param name="startIndex">The index in the input string to start appending from.</param>
- /// <param name="count">The count of characters to copy from the input string, or -1 for all remaining.</param>
- /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
- /// <exception cref="ArgumentOutOfRangeException">
- /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
- /// of <paramref name="value"/> characters.
- /// </exception>
- public void Append(string value, int startIndex = 0, int count = -1)
- {
- CopyFrom(
- bufferIndex: _length,
- source: value,
- sourceIndex: startIndex,
- count: count);
- }
-
- /// <summary>
/// Append the given buffer.
/// </summary>
/// <param name="value">The buffer to append.</param>
@@ -208,14 +174,13 @@ namespace System.Runtime.InteropServices
/// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
/// of <paramref name="value"/> characters.
/// </exception>
- public void Append(StringBuffer value, uint startIndex = 0)
+ public void Append(ref StringBuffer value, int startIndex = 0)
{
- if (value == null) throw new ArgumentNullException(nameof(value));
if (value.Length == 0) return;
value.CopyTo(
bufferIndex: startIndex,
- destination: this,
+ destination: ref this,
destinationIndex: _length,
count: value.Length);
}
@@ -231,14 +196,13 @@ namespace System.Runtime.InteropServices
/// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
/// of <paramref name="value"/> characters.
/// </exception>
- public void Append(StringBuffer value, uint startIndex, uint count)
+ public void Append(ref StringBuffer value, int startIndex, int count)
{
- if (value == null) throw new ArgumentNullException(nameof(value));
if (count == 0) return;
value.CopyTo(
bufferIndex: startIndex,
- destination: this,
+ destination: ref this,
destinationIndex: _length,
count: count);
}
@@ -252,29 +216,24 @@ namespace System.Runtime.InteropServices
/// of <paramref name="value"/> characters.
/// </exception>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="destination"/> is null.</exception>
- public unsafe void CopyTo(uint bufferIndex, StringBuffer destination, uint destinationIndex, uint count)
+ public void CopyTo(int bufferIndex, ref StringBuffer destination, int destinationIndex, int count)
{
- if (destination == null) throw new ArgumentNullException(nameof(destination));
if (destinationIndex > destination._length) throw new ArgumentOutOfRangeException(nameof(destinationIndex));
if (bufferIndex >= _length) throw new ArgumentOutOfRangeException(nameof(bufferIndex));
if (_length < checked(bufferIndex + count)) throw new ArgumentOutOfRangeException(nameof(count));
if (count == 0) return;
- uint lastIndex = checked(destinationIndex + count);
- if (destination._length < lastIndex) destination.Length = lastIndex;
-
- Buffer.MemoryCopy(
- source: CharPointer + bufferIndex,
- destination: destination.CharPointer + destinationIndex,
- destinationSizeInBytes: checked((long)(destination.ByteCapacity - (destinationIndex * sizeof(char)))),
- sourceBytesToCopy: checked((long)count * sizeof(char)));
+ int lastIndex = checked(destinationIndex + count);
+ if (destination.Length < lastIndex) destination.Length = lastIndex;
+
+ Array.Copy(UnderlyingArray, bufferIndex, destination.UnderlyingArray, destinationIndex, count);
}
/// <summary>
/// Copy contents from the specified string into the buffer at the given index. Start index must be within the current length of
/// the buffer, will grow as necessary.
/// </summary>
- public unsafe void CopyFrom(uint bufferIndex, string source, int sourceIndex = 0, int count = -1)
+ public void CopyFrom(int bufferIndex, string source, int sourceIndex = 0, int count = -1)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (bufferIndex > _length) throw new ArgumentOutOfRangeException(nameof(bufferIndex));
@@ -283,32 +242,22 @@ namespace System.Runtime.InteropServices
if (count < 0 || source.Length - count < sourceIndex) throw new ArgumentOutOfRangeException(nameof(count));
if (count == 0) return;
- uint lastIndex = bufferIndex + (uint)count;
+ int lastIndex = bufferIndex + (int)count;
if (_length < lastIndex) Length = lastIndex;
- fixed (char* content = source)
- {
- Buffer.MemoryCopy(
- source: content + sourceIndex,
- destination: CharPointer + bufferIndex,
- destinationSizeInBytes: checked((long)(ByteCapacity - (bufferIndex * sizeof(char)))),
- sourceBytesToCopy: (long)count * sizeof(char));
- }
+ source.CopyTo(sourceIndex, UnderlyingArray, bufferIndex, count);
}
/// <summary>
/// Trim the specified values from the end of the buffer. If nothing is specified, nothing is trimmed.
/// </summary>
- public unsafe void TrimEnd(char[] values)
+ public void TrimEnd(char[] values)
{
if (values == null || values.Length == 0 || _length == 0) return;
- char* end = CharPointer + _length - 1;
-
- while (_length > 0 && Array.IndexOf(values, *end) >= 0)
+ while (_length > 0 && Array.IndexOf(values, _buffer[_length - 1]) >= 0)
{
Length = _length - 1;
- end--;
}
}
@@ -316,11 +265,9 @@ namespace System.Runtime.InteropServices
/// String representation of the entire buffer. If the buffer is larger than the maximum size string (int.MaxValue) this will throw.
/// </summary>
/// <exception cref="InvalidOperationException">Thrown if the buffer is too big to fit into a string.</exception>
- public unsafe override string ToString()
+ public override string ToString()
{
- if (_length == 0) return string.Empty;
- if (_length > int.MaxValue) throw new InvalidOperationException();
- return new string(CharPointer, startIndex: 0, length: (int)_length);
+ return new string(_buffer, startIndex: 0, length: _length);
}
/// <summary>
@@ -331,23 +278,23 @@ namespace System.Runtime.InteropServices
/// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range of the buffer's length
/// or count is greater than the maximum string size (int.MaxValue).
/// </exception>
- public unsafe string Substring(uint startIndex, int count = -1)
+ public string Substring(int startIndex, int count = -1)
{
if (startIndex > (_length == 0 ? 0 : _length - 1)) throw new ArgumentOutOfRangeException(nameof(startIndex));
if (count < -1) throw new ArgumentOutOfRangeException(nameof(count));
- uint realCount = count == -1 ? _length - startIndex : (uint)count;
+ int realCount = count == -1 ? _length - startIndex : (int)count;
if (realCount > int.MaxValue || checked(startIndex + realCount) > _length) throw new ArgumentOutOfRangeException(nameof(count));
- if (realCount == 0) return string.Empty;
// The buffer could be bigger than will fit into a string, but the substring might fit. As the starting
// index might be bigger than int we need to index ourselves.
- return new string(value: CharPointer + startIndex, startIndex: 0, length: (int)realCount);
+ return new string(_buffer, startIndex: startIndex, length: realCount);
}
- public override void Free()
+ public void Free()
{
- base.Free();
+ ArrayPool<char>.Shared.Return(_buffer);
+ _buffer = null;
_length = 0;
}
}
diff --git a/src/mscorlib/corefx/System/Security/SecureString.Windows.cs b/src/mscorlib/corefx/System/Security/SecureString.Windows.cs
index 5f56353647..7ed0c6a15b 100644
--- a/src/mscorlib/corefx/System/Security/SecureString.Windows.cs
+++ b/src/mscorlib/corefx/System/Security/SecureString.Windows.cs
@@ -206,11 +206,11 @@ namespace System.Security
else
{
uint defaultChar = '?';
- int resultByteLength = 1 + Interop.mincore.WideCharToMultiByte(
- Interop.mincore.CP_ACP, Interop.mincore.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, null, 0, (IntPtr)(&defaultChar), IntPtr.Zero);
+ int resultByteLength = 1 + Interop.Kernel32.WideCharToMultiByte(
+ Interop.Kernel32.CP_ACP, Interop.Kernel32.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, null, 0, (IntPtr)(&defaultChar), IntPtr.Zero);
ptr = globalAlloc ? Marshal.AllocHGlobal(resultByteLength) : Marshal.AllocCoTaskMem(resultByteLength);
- Interop.mincore.WideCharToMultiByte(
- Interop.mincore.CP_ACP, Interop.mincore.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, (byte*)ptr, resultByteLength - 1, (IntPtr)(&defaultChar), IntPtr.Zero);
+ Interop.Kernel32.WideCharToMultiByte(
+ Interop.Kernel32.CP_ACP, Interop.Kernel32.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, (byte*)ptr, resultByteLength - 1, (IntPtr)(&defaultChar), IntPtr.Zero);
*(resultByteLength - 1 + (byte*)ptr) = 0;
}
result = ptr;