Use Roslyn support for RuntimeHelpers.CreateSpan (or field caching downlevel) (#79461)
authorStephen Toub <stoub@microsoft.com>
Fri, 13 Jan 2023 16:04:50 +0000 (11:04 -0500)
committerGitHub <noreply@github.com>
Fri, 13 Jan 2023 16:04:50 +0000 (11:04 -0500)
48 files changed:
src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.manual.cs
src/libraries/Common/src/System/Security/IdentityHelper.cs
src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDateTime.cs
src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs
src/libraries/System.Drawing.Primitives/src/System/Drawing/KnownColorTable.cs
src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateManaged/InflaterManaged.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs
src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Helpers.cs
src/libraries/System.Private.CoreLib/src/System/Convert.cs
src/libraries/System.Private.CoreLib/src/System/DateTime.Windows.cs
src/libraries/System.Private.CoreLib/src/System/DateTime.cs
src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CalendricalCalculationsHelper.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/EastAsianLunisolarCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendarHelper.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/HijriCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/IcuLocaleData.generator.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/JulianCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/PersianCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Math.cs
src/libraries/System.Private.CoreLib/src/System/MathF.cs
src/libraries/System.Private.CoreLib/src/System/Number.BigInteger.cs
src/libraries/System.Private.CoreLib/src/System/Number.Grisu3.cs
src/libraries/System.Private.CoreLib/src/System/Number.NumberToFloatingPointBits.cs
src/libraries/System.Private.CoreLib/src/System/Text/EncoderLatin1BestFitFallback.Data.cs
src/libraries/System.Private.CoreLib/src/System/Text/EncoderLatin1BestFitFallback.cs
src/libraries/System.Private.CoreLib/src/System/Text/EncodingData.cs
src/libraries/System.Private.CoreLib/src/System/Text/EncodingTable.cs
src/libraries/System.Private.CoreLib/src/System/Text/UTF7Encoding.cs
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs
src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ObjectToIdCache.cs
src/libraries/System.Private.DataContractSerialization/src/System/Xml/UniqueId.cs
src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XNodeNavigator.cs
src/libraries/System.Private.Xml/src/System/Xml/Base64Decoder.cs
src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdBuilder.cs
src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdDateTime.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/NumberFormatter.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPathConvert.cs
src/libraries/System.Runtime.Numerics/src/System/Numerics/BigNumber.cs
src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHAHashProvider.Browser.Managed.cs
src/libraries/System.Text.Encoding.CodePages/src/Data/Tools/EncodingDataGenerator.cs
src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncodingTable.Data.cs
src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncodingTable.cs
src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.Date.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCaseEquivalences.Data.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCaseEquivalences.cs
src/libraries/System.Text.RegularExpressions/tools/DataTable.cs

index 8ab8093c29e67719f1e6ddb54522905fe65cafda..eade371efe4f6341e203371de9ffccc97abe20ae 100644 (file)
@@ -12,7 +12,7 @@ namespace System.Security.Cryptography.Asn1
     // smallest supported by .NET that's not really a problem.
     internal partial struct Rc2CbcParameters
     {
-        private static readonly byte[] s_rc2EkbEncoding =
+        private static ReadOnlySpan<byte> Rc2EkbEncoding => new byte[]
         {
             0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0,
             0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a,
@@ -34,26 +34,16 @@ namespace System.Security.Cryptography.Asn1
 
         internal Rc2CbcParameters(ReadOnlyMemory<byte> iv, int keySize)
         {
-            if (keySize > byte.MaxValue)
-            {
-                Rc2Version = keySize;
-            }
-            else
-            {
-                Rc2Version = s_rc2EkbEncoding[keySize];
-            }
+            Rc2Version = keySize > byte.MaxValue ?
+                keySize :
+                Rc2EkbEncoding[keySize];
 
             Iv = iv;
         }
 
-        internal int GetEffectiveKeyBits()
-        {
-            if (Rc2Version > byte.MaxValue)
-            {
-                return Rc2Version;
-            }
-
-            return Array.IndexOf(s_rc2EkbEncoding, (byte)Rc2Version);
-        }
+        internal int GetEffectiveKeyBits() =>
+            Rc2Version > byte.MaxValue ?
+                Rc2Version :
+                Rc2EkbEncoding.IndexOf((byte)Rc2Version);
     }
 }
index 9ce528a47c347fa2c7a233c477aa22c711cb2ebb..5f60a8758d99d6069a83ea96d5f25edf94e66fcc 100644 (file)
@@ -15,14 +15,6 @@ namespace System.Security
     /// </summary>
     internal static class IdentityHelper
     {
-        private static readonly char[] s_base32Char =
-        {
-            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
-            'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
-            'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
-            'y', 'z', '0', '1', '2', '3', '4', '5'
-        };
-
         /// <summary>
         /// Gives a hash equivalent to what Url.Normalize() gives.
         /// </summary>
@@ -95,6 +87,7 @@ namespace System.Security
             // Create l chars using the last 5 bits of each byte.
             // Consume 3 MSB bits 5 bytes at a time.
 
+            ReadOnlySpan<byte> base32Chars = "abcdefghijklmnopqrstuvwxyz012345"u8;
             do
             {
                 byte b0 = (i < l) ? buff[i++] : (byte)0;
@@ -104,18 +97,18 @@ namespace System.Security
                 byte b4 = (i < l) ? buff[i++] : (byte)0;
 
                 // Consume the 5 Least significant bits of each byte
-                sb.Append(s_base32Char[b0 & 0x1F]);
-                sb.Append(s_base32Char[b1 & 0x1F]);
-                sb.Append(s_base32Char[b2 & 0x1F]);
-                sb.Append(s_base32Char[b3 & 0x1F]);
-                sb.Append(s_base32Char[b4 & 0x1F]);
+                sb.Append((char)base32Chars[b0 & 0x1F]);
+                sb.Append((char)base32Chars[b1 & 0x1F]);
+                sb.Append((char)base32Chars[b2 & 0x1F]);
+                sb.Append((char)base32Chars[b3 & 0x1F]);
+                sb.Append((char)base32Chars[b4 & 0x1F]);
 
                 // Consume 3 MSB of b0, b1, MSB bits 6, 7 of b3, b4
-                sb.Append(s_base32Char[(
+                sb.Append((char)base32Chars[(
                         ((b0 & 0xE0) >> 5) |
                         ((b3 & 0x60) >> 2))]);
 
-                sb.Append(s_base32Char[(
+                sb.Append((char)base32Chars[(
                         ((b1 & 0xE0) >> 5) |
                         ((b4 & 0x60) >> 2))]);
 
@@ -130,7 +123,7 @@ namespace System.Security
                 if ((b4 & 0x80) != 0)
                     b2 |= 0x10;
 
-                sb.Append(s_base32Char[b2]);
+                sb.Append((char)base32Chars[b2]);
 
             } while (i < l);
 
index 86e290eadf6d859e6114a60e19350531a6a40a41..1b9ca9c078c4a342e765d97876b34b5c756ef9f6 100644 (file)
@@ -36,8 +36,6 @@ namespace System.Data.SqlTypes
         public static readonly int SQLTicksPerHour = SQLTicksPerMinute * 60;
         private static readonly int s_SQLTicksPerDay = SQLTicksPerHour * 24;
 
-        private const long s_ticksPerSecond = TimeSpan.TicksPerMillisecond * 1000;
-
         private static readonly DateTime s_SQLBaseDate = new DateTime(1900, 1, 1);
         private static readonly long s_SQLBaseDateTicks = s_SQLBaseDate.Ticks;
 
@@ -51,17 +49,14 @@ namespace System.Data.SqlTypes
 
         private const int s_dayBase = 693595;               // Jan 1 1900 is this many days from Jan 1 0001
 
-
-        private static readonly int[] s_daysToMonth365 = new int[] {
+        private static ReadOnlySpan<int> DaysToMonth365 => new int[] {
             0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
-        private static readonly int[] s_daysToMonth366 = new int[] {
+        private static ReadOnlySpan<int> DaysToMonth366 => new int[] {
             0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
 
-        private static readonly DateTime s_minDateTime = new DateTime(1753, 1, 1);
-        private static readonly DateTime s_maxDateTime = DateTime.MaxValue;
-        private static readonly TimeSpan s_minTimeSpan = s_minDateTime.Subtract(s_SQLBaseDate);
-        private static readonly TimeSpan s_maxTimeSpan = s_maxDateTime.Subtract(s_SQLBaseDate);
-        private const string s_ISO8601_DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fff";
+        private static readonly TimeSpan s_minTimeSpan = new DateTime(1753, 1, 1).Subtract(s_SQLBaseDate);
+        private static readonly TimeSpan s_maxTimeSpan = DateTime.MaxValue.Subtract(s_SQLBaseDate);
+        private const string ISO8601_DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fff";
 
         // These formats are valid styles in SQL Server (style 9, 12, 13, 14)
         // but couldn't be recognized by the default parse. Needs to call
@@ -105,7 +100,9 @@ namespace System.Data.SqlTypes
         {
             if (year >= s_minYear && year <= s_maxYear && month >= 1 && month <= 12)
             {
-                int[] days = IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365;
+                ReadOnlySpan<int> days = IsLeapYear(year) ?
+                    DaysToMonth366 :
+                    DaysToMonth365;
                 if (day >= 1 && day <= days[month] - days[month - 1])
                 {
                     int y = year - 1;
@@ -670,7 +667,7 @@ namespace System.Data.SqlTypes
             }
             else
             {
-                writer.WriteString(XmlConvert.ToString(Value, s_ISO8601_DateTimeFormat));
+                writer.WriteString(XmlConvert.ToString(Value, ISO8601_DateTimeFormat));
             }
         }
 
index 23a37786006e8cef0d9b900461d7f6f185583b34..79bb3d871a31b4b286466f7d6461779fd1d21a2d 100644 (file)
@@ -71,7 +71,7 @@ namespace System.Data.SqlTypes
         private const byte s_cNumeDivScaleMin = 6;     // Minimum result scale of numeric division
 
         // Array of multipliers for lAdjust and Ceiling/Floor.
-        private static readonly uint[] s_rgulShiftBase = new uint[9] {
+        private static ReadOnlySpan<uint> RgulShiftBase => new uint[9] {
             10,
             10 * 10,
             10 * 10 * 10,
@@ -130,7 +130,7 @@ namespace System.Data.SqlTypes
         #endregion
 
         #region DecimalHelperTable
-        private static readonly uint[] s_decimalHelpersLo = {
+        private static ReadOnlySpan<uint> DecimalHelpersLo => new uint[] {
             0x0000000a, // precision:2, value:10
             0x00000064, // precision:3, value:100
             0x000003e8, // precision:4, value:1000
@@ -171,7 +171,7 @@ namespace System.Data.SqlTypes
             0x00000000, // precision:38+1, value:99999999999999999999999999999999999999+1
         };
 
-        private static readonly uint[] s_decimalHelpersMid = {
+        private static ReadOnlySpan<uint> DecimalHelpersMid => new uint[] {
             0x00000000, // precision:2, value:10
             0x00000000, // precision:3, value:100
             0x00000000, // precision:4, value:1000
@@ -212,7 +212,7 @@ namespace System.Data.SqlTypes
             0x098a2240, // precision:38+1, value:99999999999999999999999999999999999999+1
         };
 
-        private static readonly uint[] s_decimalHelpersHi = {
+        private static ReadOnlySpan<uint> DecimalHelpersHi => new uint[] {
             0x00000000, // precision:2, value:10
             0x00000000, // precision:3, value:100
             0x00000000, // precision:4, value:1000
@@ -253,7 +253,7 @@ namespace System.Data.SqlTypes
             0x5a86c47a, // precision:38+1, value:99999999999999999999999999999999999999+1
         };
 
-        private static readonly uint[] s_decimalHelpersHiHi = {
+        private static ReadOnlySpan<uint> DecimalHelpersHiHi => new uint[] {
             0x00000000, // precision:2, value:10
             0x00000000, // precision:3, value:100
             0x00000000, // precision:4, value:1000
@@ -313,31 +313,31 @@ namespace System.Data.SqlTypes
         {
             int tableIndex;
             byte precision;
-            uint[] decimalHelpers;
+            ReadOnlySpan<uint> decimalHelpers;
             uint decimalPart;
 
             if (_data4 != 0)
             {
                 tableIndex = HelperTableStartIndexHiHi;
-                decimalHelpers = s_decimalHelpersHiHi;
+                decimalHelpers = DecimalHelpersHiHi;
                 decimalPart = _data4;
             }
             else if (_data3 != 0)
             {
                 tableIndex = HelperTableStartIndexHi;
-                decimalHelpers = s_decimalHelpersHi;
+                decimalHelpers = DecimalHelpersHi;
                 decimalPart = _data3;
             }
             else if (_data2 != 0)
             {
                 tableIndex = HelperTableStartIndexMid;
-                decimalHelpers = s_decimalHelpersMid;
+                decimalHelpers = DecimalHelpersMid;
                 decimalPart = _data2;
             }
             else
             {
                 tableIndex = HelperTableStartIndexLo;
-                decimalHelpers = s_decimalHelpersLo;
+                decimalHelpers = DecimalHelpersLo;
                 decimalPart = _data1;
             }
 
@@ -429,25 +429,25 @@ namespace System.Data.SqlTypes
             Debug.Assert(precision <= MaxPrecision, "Precision > MaxPrecision");
 
             int tableIndex = checked((precision - 1));
-            if (_data4 < s_decimalHelpersHiHi[tableIndex])
+            if (_data4 < DecimalHelpersHiHi[tableIndex])
             {
                 return true;
             }
-            else if (_data4 == s_decimalHelpersHiHi[tableIndex])
+            else if (_data4 == DecimalHelpersHiHi[tableIndex])
             {
-                if (_data3 < s_decimalHelpersHi[tableIndex])
+                if (_data3 < DecimalHelpersHi[tableIndex])
                 {
                     return true;
                 }
-                else if (_data3 == s_decimalHelpersHi[tableIndex])
+                else if (_data3 == DecimalHelpersHi[tableIndex])
                 {
-                    if (_data2 < s_decimalHelpersMid[tableIndex])
+                    if (_data2 < DecimalHelpersMid[tableIndex])
                     {
                         return true;
                     }
-                    else if (_data2 == s_decimalHelpersMid[tableIndex])
+                    else if (_data2 == DecimalHelpersMid[tableIndex])
                     {
-                        if (_data1 < s_decimalHelpersLo[tableIndex])
+                        if (_data1 < DecimalHelpersLo[tableIndex])
                         {
                             return true;
                         }
@@ -754,9 +754,9 @@ namespace System.Data.SqlTypes
                 {
                     ulLenDelta = (ulLen >= 9) ? 9 : ulLen;
 
-                    dFrac *= s_rgulShiftBase[(int)ulLenDelta - 1];
+                    dFrac *= RgulShiftBase[(int)ulLenDelta - 1];
                     ulLen -= ulLenDelta;
-                    MultByULong(s_rgulShiftBase[(int)ulLenDelta - 1]);
+                    MultByULong(RgulShiftBase[(int)ulLenDelta - 1]);
                     AddULong((uint)dFrac);
                     dFrac -= Math.Floor(dFrac);
                 }
@@ -1542,12 +1542,12 @@ namespace System.Data.SqlTypes
                     {
                         if (lScaleAdjust <= -9)
                         {
-                            ulShiftBase = s_rgulShiftBase[8];
+                            ulShiftBase = RgulShiftBase[8];
                             lScaleAdjust += 9;
                         }
                         else
                         {
-                            ulShiftBase = s_rgulShiftBase[-lScaleAdjust - 1];
+                            ulShiftBase = RgulShiftBase[-lScaleAdjust - 1];
                             lScaleAdjust = 0;
                         }
                         MpDiv1(rgulRes, ref culRes, ulShiftBase, out ulRem);
@@ -2304,12 +2304,12 @@ namespace System.Data.SqlTypes
                     //if lAdjust>=9, downshift by 10^9 each time, otherwise by the full amount
                     if (lAdjust >= 9)
                     {
-                        ulShiftBase = s_rgulShiftBase[8];
+                        ulShiftBase = RgulShiftBase[8];
                         lAdjust -= 9;
                     }
                     else
                     {
-                        ulShiftBase = s_rgulShiftBase[lAdjust - 1];
+                        ulShiftBase = RgulShiftBase[lAdjust - 1];
                         lAdjust = 0;
                     }
                     MultByULong(ulShiftBase);
@@ -2321,12 +2321,12 @@ namespace System.Data.SqlTypes
                 {
                     if (lAdjust <= -9)
                     {
-                        ulShiftBase = s_rgulShiftBase[8];
+                        ulShiftBase = RgulShiftBase[8];
                         lAdjust += 9;
                     }
                     else
                     {
-                        ulShiftBase = s_rgulShiftBase[-lAdjust - 1];
+                        ulShiftBase = RgulShiftBase[-lAdjust - 1];
                         lAdjust = 0;
                     }
                     ulRem = DivByULong(ulShiftBase);
@@ -3051,12 +3051,12 @@ namespace System.Data.SqlTypes
             {
                 if (iAdjust >= 9)
                 {
-                    ulRem = DivByULong(s_rgulShiftBase[8]);
+                    ulRem = DivByULong(RgulShiftBase[8]);
                     iAdjust -= 9;
                 }
                 else
                 {
-                    ulRem = DivByULong(s_rgulShiftBase[iAdjust - 1]);
+                    ulRem = DivByULong(RgulShiftBase[iAdjust - 1]);
                     iAdjust = 0;
                 }
 
@@ -3189,14 +3189,14 @@ namespace System.Data.SqlTypes
             {
                 if (lAdjust >= 9)
                 {
-                    ulRem = n.DivByULong(s_rgulShiftBase[8]);
-                    ulLastDivBase = s_rgulShiftBase[8];
+                    ulRem = n.DivByULong(RgulShiftBase[8]);
+                    ulLastDivBase = RgulShiftBase[8];
                     lAdjust -= 9;
                 }
                 else
                 {
-                    ulRem = n.DivByULong(s_rgulShiftBase[lAdjust - 1]);
-                    ulLastDivBase = s_rgulShiftBase[lAdjust - 1];
+                    ulRem = n.DivByULong(RgulShiftBase[lAdjust - 1]);
+                    ulLastDivBase = RgulShiftBase[lAdjust - 1];
                     lAdjust = 0;
                 }
             }
index 281f246d13ade8fc5a3aa813f9c8f2be4ff0be58..3ec5d7ab825cb6988c099ae0390d8b8658ade861 100644 (file)
@@ -12,7 +12,7 @@ namespace System.Drawing
         public const byte KnownColorKindUnknown = 2;
 
         // All known color values (in order of definition in the KnownColor enum).
-        public static readonly uint[] s_colorValueTable = new uint[]
+        public static ReadOnlySpan<uint> ColorValueTable => new uint[]
         {
             // "not a known color"
             0,
@@ -466,11 +466,12 @@ namespace System.Drawing
         internal static Color ArgbToKnownColor(uint argb)
         {
             Debug.Assert((argb & Color.ARGBAlphaMask) == Color.ARGBAlphaMask);
-            Debug.Assert(s_colorValueTable.Length == ColorKindTable.Length);
+            Debug.Assert(ColorValueTable.Length == ColorKindTable.Length);
 
-            for (int index = 1; index < s_colorValueTable.Length; ++index)
+            ReadOnlySpan<uint> colorValueTable = ColorValueTable;
+            for (int index = 1; index < colorValueTable.Length; ++index)
             {
-                if (ColorKindTable[index] == KnownColorKindWeb && s_colorValueTable[index] == argb)
+                if (ColorKindTable[index] == KnownColorKindWeb && colorValueTable[index] == argb)
                 {
                     return Color.FromKnownColor((KnownColor)index);
                 }
@@ -486,7 +487,7 @@ namespace System.Drawing
 
             return ColorKindTable[(int)color] == KnownColorKindSystem
                  ? GetSystemColorArgb(color)
-                 : s_colorValueTable[(int)color];
+                 : ColorValueTable[(int)color];
         }
 
 #if FEATURE_WINDOWS_SYSTEM_COLORS
@@ -494,14 +495,14 @@ namespace System.Drawing
         {
             Debug.Assert(Color.IsKnownColorSystem(color));
 
-            return ColorTranslator.COLORREFToARGB(Interop.User32.GetSysColor((byte)s_colorValueTable[(int)color]));
+            return ColorTranslator.COLORREFToARGB(Interop.User32.GetSysColor((byte)ColorValueTable[(int)color]));
         }
 #else
         public static uint GetSystemColorArgb(KnownColor color)
         {
             Debug.Assert(Color.IsKnownColorSystem(color));
 
-            return s_colorValueTable[(int)color];
+            return ColorValueTable[(int)color];
         }
 #endif
     }
index 4dce72fb505a8e93f19922509af4005a5396546e..fd75b5ac0213cbee747b4f0837934cb375bc96ce 100644 (file)
@@ -18,7 +18,7 @@ namespace System.IO.Compression
 
         // The base length for length code 257 - 285.
         // The formula to get the real length for a length code is lengthBase[code - 257] + (value stored in extraBits)
-        private static readonly int[] s_lengthBase =
+        private static ReadOnlySpan<byte> LengthBase => new byte[]
         {
             3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51,
             59, 67, 83, 99, 115, 131, 163, 195, 227, 3
@@ -26,7 +26,7 @@ namespace System.IO.Compression
 
         // The base distance for distance code 0 - 31
         // The real distance for a distance code is  distanceBasePosition[code] + (value stored in extraBits)
-        private static readonly int[] s_distanceBasePosition =
+        private static ReadOnlySpan<ushort> DistanceBasePosition => new ushort[]
         {
             1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
             769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153
@@ -410,11 +410,11 @@ namespace System.IO.Compression
                                 return false;
                             }
 
-                            if (_length < 0 || _length >= s_lengthBase.Length)
+                            if (_length < 0 || _length >= LengthBase.Length)
                             {
                                 throw new InvalidDataException(SR.GenericInvalidData);
                             }
-                            _length = s_lengthBase[_length] + bits;
+                            _length = LengthBase[_length] + bits;
                         }
                         _state = InflaterState.HaveFullLength;
                         goto case InflaterState.HaveFullLength;
@@ -456,7 +456,7 @@ namespace System.IO.Compression
                             {
                                 return false;
                             }
-                            offset = s_distanceBasePosition[_distanceCode] + bits;
+                            offset = DistanceBasePosition[_distanceCode] + bits;
                         }
                         else
                         {
index 7557ece3e264e00ec3304819aa098cc698d94259..d5199afc6deb50dbd2ff361d8e998b34738ea91c 100644 (file)
@@ -480,7 +480,7 @@ namespace System.Net.Http
             private const int FirstHPackNormalHeaderId = 15;
             private const int LastHPackNormalHeaderId = 61;
 
-            private static readonly int[] s_hpackStaticStatusCodeTable = new int[LastHPackStatusPseudoHeaderId - FirstHPackStatusPseudoHeaderId + 1] { 200, 204, 206, 304, 400, 404, 500 };
+            private static ReadOnlySpan<int> HpackStaticStatusCodeTable => new int[LastHPackStatusPseudoHeaderId - FirstHPackStatusPseudoHeaderId + 1] { 200, 204, 206, 304, 400, 404, 500 };
 
             private static readonly (HeaderDescriptor descriptor, byte[] value)[] s_hpackStaticHeaderTable = new (HeaderDescriptor, byte[])[LastHPackNormalHeaderId - FirstHPackNormalHeaderId + 1]
             {
@@ -544,7 +544,7 @@ namespace System.Net.Http
                 }
                 else if (index <= LastHPackStatusPseudoHeaderId)
                 {
-                    int statusCode = s_hpackStaticStatusCodeTable[index - FirstHPackStatusPseudoHeaderId];
+                    int statusCode = HpackStaticStatusCodeTable[index - FirstHPackStatusPseudoHeaderId];
 
                     OnStatus(statusCode);
                 }
index 8dcea70dbf14e0feca7ce4c698cacd91a6b20df0..763aa4d9711ae4be17b80dbc9cbc6ed61486fbe6 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Diagnostics;
+using System.Globalization;
 
 namespace System.Buffers.Text
 {
@@ -144,7 +145,7 @@ namespace System.Buffers.Text
 
             Debug.Assert(fraction >= 0 && fraction <= Utf8Constants.MaxDateTimeFraction); // All of our callers to date parse the fraction from fixed 7-digit fields so this value is trusted.
 
-            int[] days = DateTime.IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<int> days = DateTime.IsLeapYear(year) ? GregorianCalendar.DaysToMonth366 : GregorianCalendar.DaysToMonth365;
             int yearMinusOne = year - 1;
             int totalDays = (yearMinusOne * 365) + (yearMinusOne / 4) - (yearMinusOne / 100) + (yearMinusOne / 400) + days[month - 1] + day - 1;
             long ticks = totalDays * TimeSpan.TicksPerDay;
@@ -154,8 +155,5 @@ namespace System.Buffers.Text
             value = new DateTime(ticks: ticks, kind: kind);
             return true;
         }
-
-        private static readonly int[] s_daysToMonth365 = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
-        private static readonly int[] s_daysToMonth366 = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
     }
 }
index 6899925d140b390f68df3b9df3c5c0771a475f21..880bc2f6599ef8249166be852cebd1838ee4312a 100644 (file)
@@ -102,8 +102,6 @@ namespace System
         // Need to special case Enum because typecode will be underlying type, e.g. Int32
         private static readonly Type EnumType = typeof(Enum);
 
-        internal const string Base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-
         private const int Base64LineBreakPosition = 76;
         private const int Base64VectorizationLengthThreshold = 16;
 
@@ -2535,8 +2533,8 @@ namespace System
             // Convert three bytes at a time to base64 notation.  This will consume 4 chars.
             int i;
 
-            // get a pointer to the Base64Table to avoid unnecessary range checking
-            fixed (char* base64 = Base64Table)
+            // get a pointer to the base64 table to avoid unnecessary range checking
+            fixed (byte* base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="u8)
             {
                 for (i = offset; i < calcLength; i += 3)
                 {
@@ -2550,10 +2548,10 @@ namespace System
                         }
                         charcount += 4;
                     }
-                    outChars[j] = base64[(inData[i] & 0xfc) >> 2];
-                    outChars[j + 1] = base64[((inData[i] & 0x03) << 4) | ((inData[i + 1] & 0xf0) >> 4)];
-                    outChars[j + 2] = base64[((inData[i + 1] & 0x0f) << 2) | ((inData[i + 2] & 0xc0) >> 6)];
-                    outChars[j + 3] = base64[inData[i + 2] & 0x3f];
+                    outChars[j] = (char)base64[(inData[i] & 0xfc) >> 2];
+                    outChars[j + 1] = (char)base64[((inData[i] & 0x03) << 4) | ((inData[i + 1] & 0xf0) >> 4)];
+                    outChars[j + 2] = (char)base64[((inData[i + 1] & 0x0f) << 2) | ((inData[i + 2] & 0xc0) >> 6)];
+                    outChars[j + 3] = (char)base64[inData[i + 2] & 0x3f];
                     j += 4;
                 }
 
@@ -2569,17 +2567,17 @@ namespace System
                 switch (lengthmod3)
                 {
                     case 2: // One character padding needed
-                        outChars[j] = base64[(inData[i] & 0xfc) >> 2];
-                        outChars[j + 1] = base64[((inData[i] & 0x03) << 4) | ((inData[i + 1] & 0xf0) >> 4)];
-                        outChars[j + 2] = base64[(inData[i + 1] & 0x0f) << 2];
-                        outChars[j + 3] = base64[64]; // Pad
+                        outChars[j] = (char)base64[(inData[i] & 0xfc) >> 2];
+                        outChars[j + 1] = (char)base64[((inData[i] & 0x03) << 4) | ((inData[i + 1] & 0xf0) >> 4)];
+                        outChars[j + 2] = (char)base64[(inData[i + 1] & 0x0f) << 2];
+                        outChars[j + 3] = (char)base64[64]; // Pad
                         j += 4;
                         break;
                     case 1: // Two character padding needed
-                        outChars[j] = base64[(inData[i] & 0xfc) >> 2];
-                        outChars[j + 1] = base64[(inData[i] & 0x03) << 4];
-                        outChars[j + 2] = base64[64]; // Pad
-                        outChars[j + 3] = base64[64]; // Pad
+                        outChars[j] = (char)base64[(inData[i] & 0xfc) >> 2];
+                        outChars[j + 1] = (char)base64[(inData[i] & 0x03) << 4];
+                        outChars[j + 2] = (char)base64[64]; // Pad
+                        outChars[j + 3] = (char)base64[64]; // Pad
                         j += 4;
                         break;
                 }
index 1b72fccb3f4ec7b11022e66679b6c7ed7224c1f6..e435255365e8f4dd9b570c33c526e34b13d7f6e1 100644 (file)
@@ -109,7 +109,7 @@ namespace System
         private static DateTime CreateDateTimeFromSystemTime(in Interop.Kernel32.SYSTEMTIME time, ulong hundredNanoSecond)
         {
             uint year = time.Year;
-            uint[] days = IsLeapYear((int)year) ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<uint> days = IsLeapYear((int)year) ? DaysToMonth366 : DaysToMonth365;
             int month = time.Month - 1;
             uint n = DaysToYear(year) + days[month] + time.Day - 1;
             ulong ticks = n * (ulong)TicksPerDay;
index 0f56dbaaeb58f722e1657f1498c36b1d4b98417f..e47533c785c8fa2a909c7ce95d9d233cb0958c6c 100644 (file)
@@ -120,9 +120,9 @@ namespace System
         private const ulong TicksPer6Hours = TicksPerHour * 6;
         private const int March1BasedDayOfNewYear = 306;              // Days between March 1 and January 1
 
-        private static readonly uint[] s_daysToMonth365 = {
+        internal static ReadOnlySpan<uint> DaysToMonth365 => new uint[] {
             0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
-        private static readonly uint[] s_daysToMonth366 = {
+        internal static ReadOnlySpan<uint> DaysToMonth366 => new uint[] {
             0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
 
         private static ReadOnlySpan<byte> DaysInMonth365 => new byte[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
@@ -953,7 +953,7 @@ namespace System
             y += q;
             m -= q * 12;
             if (y < 1 || y > 9999) ThrowDateArithmetic(2);
-            uint[] daysTo = IsLeapYear(y) ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<uint> daysTo = IsLeapYear(y) ? DaysToMonth366 : DaysToMonth365;
             uint daysToMonth = daysTo[m - 1];
             int days = (int)(daysTo[m] - daysToMonth);
             if (d > days) d = days;
@@ -1016,12 +1016,12 @@ namespace System
             int m = month - 1, d = day - 1;
             if (IsLeapYear(y))
             {
-                n += s_daysToMonth366[m];
+                n += DaysToMonth366[m];
             }
             else
             {
                 if (d == 28 && m == 1) d--;
-                n += s_daysToMonth365[m];
+                n += DaysToMonth365[m];
             }
             n += (uint)d;
             return new DateTime(n * (ulong)TicksPerDay + UTicks % TicksPerDay | InternalKind);
@@ -1071,7 +1071,7 @@ namespace System
                 ThrowHelper.ThrowArgumentOutOfRange_BadYearMonthDay();
             }
 
-            uint[] days = IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<uint> days = IsLeapYear(year) ? DaysToMonth366 : DaysToMonth365;
             if ((uint)day > days[month] - days[month - 1])
             {
                 ThrowHelper.ThrowArgumentOutOfRange_BadYearMonthDay();
@@ -1952,7 +1952,7 @@ namespace System
                 return false;
             }
 
-            uint[] days = IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<uint> days = IsLeapYear(year) ? DaysToMonth366 : DaysToMonth365;
             if ((uint)day > days[month] - days[month - 1])
             {
                 return false;
index 1a5834c08d42fb4b000960025248990242a81d13..03d4943b493c4d1b042be7e3973f34874b1e9c5e 100644 (file)
@@ -101,7 +101,7 @@ namespace System
             private const int MaxInt64Scale = 19;
 
             // Fast access for 10^n where n is 0-9
-            private static readonly uint[] s_powers10 = new uint[] {
+            private static ReadOnlySpan<uint> UInt32Powers10 => new uint[] {
                 1,
                 10,
                 100,
@@ -115,7 +115,7 @@ namespace System
             };
 
             // Fast access for 10^n where n is 1-19
-            private static readonly ulong[] s_ulongPowers10 = new ulong[] {
+            private static ReadOnlySpan<ulong> UInt64Powers10 => new ulong[] {
                 10,
                 100,
                 1000,
@@ -137,7 +137,7 @@ namespace System
                 10000000000000000000,
             };
 
-            private static readonly double[] s_doublePowers10 = new double[] {
+            private static ReadOnlySpan<double> DoublePowers10 => new double[] {
                 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
                 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
                 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
@@ -931,7 +931,7 @@ ThrowOverflow:
                             {
                                 if (scale <= MaxInt32Scale)
                                 {
-                                    low64 = UInt32x32To64((uint)low64, s_powers10[scale]);
+                                    low64 = UInt32x32To64((uint)low64, UInt32Powers10[scale]);
                                     goto AlignedAdd;
                                 }
                                 scale -= MaxInt32Scale;
@@ -943,7 +943,7 @@ ThrowOverflow:
                         {
                             power = TenToPowerNine;
                             if (scale < MaxInt32Scale)
-                                power = s_powers10[scale];
+                                power = UInt32Powers10[scale];
                             tmpLow = UInt32x32To64((uint)low64, power);
                             tmp64 = UInt32x32To64((uint)(low64 >> 32), power) + (tmpLow >> 32);
                             low64 = (uint)tmpLow + (tmp64 << 32);
@@ -959,7 +959,7 @@ ThrowOverflow:
                         //
                         power = TenToPowerNine;
                         if (scale < MaxInt32Scale)
-                            power = s_powers10[scale];
+                            power = UInt32Powers10[scale];
                         tmpLow = UInt32x32To64((uint)low64, power);
                         tmp64 = UInt32x32To64((uint)(low64 >> 32), power) + (tmpLow >> 32);
                         low64 = (uint)tmpLow + (tmp64 << 32);
@@ -990,7 +990,7 @@ ThrowOverflow:
                     {
                         power = TenToPowerNine;
                         if (scale < MaxInt32Scale)
-                            power = s_powers10[scale];
+                            power = UInt32Powers10[scale];
                         tmp64 = 0;
                         uint* rgulNum = (uint*)&bufNum;
                         for (uint cur = 0; ;)
@@ -1198,7 +1198,7 @@ ReturnResult:
                 {
                     if (pdecIn.High != 0)
                         goto ThrowOverflow;
-                    uint pwr = s_powers10[-scale];
+                    uint pwr = UInt32Powers10[-scale];
                     ulong high = UInt32x32To64(pwr, pdecIn.Mid);
                     if (high > uint.MaxValue)
                         goto ThrowOverflow;
@@ -1286,7 +1286,7 @@ ThrowOverflow:
                     // Scaling loop, up to 10^9 at a time.
                     do
                     {
-                        uint power = scale >= MaxInt32Scale ? TenToPowerNine : s_powers10[scale];
+                        uint power = scale >= MaxInt32Scale ? TenToPowerNine : UInt32Powers10[scale];
                         ulong tmpLow = UInt32x32To64((uint)low64, power);
                         ulong tmp = UInt32x32To64((uint)(low64 >> 32), power) + (tmpLow >> 32);
                         low64 = (uint)tmpLow + (tmp << 32);
@@ -1345,7 +1345,7 @@ ThrowOverflow:
                                 goto ReturnZero;
 
                             scale -= DEC_SCALE_MAX + 1;
-                            ulong power = s_ulongPowers10[scale];
+                            ulong power = UInt64Powers10[scale];
 
                             // TODO: https://github.com/dotnet/runtime/issues/5213
                             tmp = low64 / power;
@@ -1562,12 +1562,12 @@ ReturnZero:
                     if (power > DEC_SCALE_MAX)
                         power = DEC_SCALE_MAX;
 
-                    dbl *= s_doublePowers10[power];
+                    dbl *= DoublePowers10[power];
                 }
                 else
                 {
                     if (power != -1 || dbl >= 1E7)
-                        dbl /= s_doublePowers10[-power];
+                        dbl /= DoublePowers10[-power];
                     else
                         power = 0; // didn't scale it
                 }
@@ -1604,7 +1604,7 @@ ReturnZero:
                     power = -power;
                     if (power < 10)
                     {
-                        result.Low64 = UInt32x32To64(mant, s_powers10[power]);
+                        result.Low64 = UInt32x32To64(mant, UInt32Powers10[power]);
                     }
                     else
                     {
@@ -1612,12 +1612,12 @@ ReturnZero:
                         //
                         if (power > 18)
                         {
-                            ulong low64 = UInt32x32To64(mant, s_powers10[power - 18]);
+                            ulong low64 = UInt32x32To64(mant, UInt32Powers10[power - 18]);
                             UInt64x64To128(low64, TenToPowerEighteen, ref result);
                         }
                         else
                         {
-                            ulong low64 = UInt32x32To64(mant, s_powers10[power - 9]);
+                            ulong low64 = UInt32x32To64(mant, UInt32Powers10[power - 9]);
                             ulong hi64 = UInt32x32To64(TenToPowerNine, (uint)(low64 >> 32));
                             low64 = UInt32x32To64(TenToPowerNine, (uint)low64);
                             result.Low = (uint)low64;
@@ -1729,12 +1729,12 @@ ReturnZero:
                     if (power > DEC_SCALE_MAX)
                         power = DEC_SCALE_MAX;
 
-                    dbl *= s_doublePowers10[power];
+                    dbl *= DoublePowers10[power];
                 }
                 else
                 {
                     if (power != -1 || dbl >= 1E15)
-                        dbl /= s_doublePowers10[-power];
+                        dbl /= DoublePowers10[-power];
                     else
                         power = 0; // didn't scale it
                 }
@@ -1771,7 +1771,7 @@ ReturnZero:
                     power = -power;
                     if (power < 10)
                     {
-                        uint pow10 = s_powers10[power];
+                        uint pow10 = UInt32Powers10[power];
                         ulong low64 = UInt32x32To64((uint)mant, pow10);
                         ulong hi64 = UInt32x32To64((uint)(mant >> 32), pow10);
                         result.Low = (uint)low64;
@@ -1785,7 +1785,7 @@ ReturnZero:
                         // Have a big power of 10.
                         //
                         Debug.Assert(power <= 14);
-                        UInt64x64To128(mant, s_ulongPowers10[power - 1], ref result);
+                        UInt64x64To128(mant, UInt64Powers10[power - 1], ref result);
                     }
                 }
                 else
@@ -1873,7 +1873,7 @@ ReturnZero:
                 const double ds2to64 = 1.8446744073709552e+019;
 
                 double dbl = ((double)value.Low64 +
-                    (double)value.High * ds2to64) / s_doublePowers10[value.Scale];
+                    (double)value.High * ds2to64) / DoublePowers10[value.Scale];
 
                 if (decimal.IsNegative(value))
                     dbl = -dbl;
@@ -1971,7 +1971,7 @@ ReturnZero:
                         }
 
                         HaveScale:
-                        power = s_powers10[curScale];
+                        power = UInt32Powers10[curScale];
                         scale += curScale;
 
                         if (IncreaseScale(ref bufQuo, power) != 0)
@@ -2053,7 +2053,7 @@ ReturnZero:
                             }
 
                             HaveScale64:
-                            power = s_powers10[curScale];
+                            power = UInt32Powers10[curScale];
                             scale += curScale;
 
                             if (IncreaseScale(ref bufQuo, power) != 0)
@@ -2124,7 +2124,7 @@ ReturnZero:
                             }
 
                             HaveScale96:
-                            power = s_powers10[curScale];
+                            power = UInt32Powers10[curScale];
                             scale += curScale;
 
                             if (IncreaseScale(ref bufQuo, power) != 0)
@@ -2209,7 +2209,7 @@ ThrowOverflow:
                     // Divisor scale can always be increased to dividend scale for remainder calculation.
                     do
                     {
-                        uint power = scale >= MaxInt32Scale ? TenToPowerNine : s_powers10[scale];
+                        uint power = scale >= MaxInt32Scale ? TenToPowerNine : UInt32Powers10[scale];
                         ulong tmp = UInt32x32To64(d2.Low, power);
                         d2.Low = (uint)tmp;
                         tmp >>= 32;
@@ -2235,7 +2235,7 @@ ThrowOverflow:
                             int iCurScale = SearchScale(ref bufQuo, DEC_SCALE_MAX + scale);
                             if (iCurScale == 0)
                                 break;
-                            uint power = iCurScale >= MaxInt32Scale ? TenToPowerNine : s_powers10[iCurScale];
+                            uint power = iCurScale >= MaxInt32Scale ? TenToPowerNine : UInt32Powers10[iCurScale];
                             scale += iCurScale;
                             ulong tmp = UInt32x32To64(bufQuo.U0, power);
                             bufQuo.U0 = (uint)tmp;
@@ -2296,7 +2296,7 @@ ThrowOverflow:
                 uint high = 3;
                 while (scale < 0)
                 {
-                    uint power = scale <= -MaxInt32Scale ? TenToPowerNine : s_powers10[-scale];
+                    uint power = scale <= -MaxInt32Scale ? TenToPowerNine : UInt32Powers10[-scale];
                     uint* buf = (uint*)&b;
                     ulong tmp64 = UInt32x32To64(b.Buf24.U0, power);
                     b.Buf24.U0 = (uint)tmp64;
@@ -2409,7 +2409,7 @@ ThrowOverflow:
                 }
 
                 {
-                    power = s_powers10[scale];
+                    power = UInt32Powers10[(int)scale];
                     // TODO: https://github.com/dotnet/runtime/issues/5213
                     uint n = d.uhi;
                     if (n == 0)
index e344048af72df928de0541b0d0932d9627009dd5..ce960764e6d82b081ab839e3f8ee9dfc63d7ecee 100644 (file)
@@ -24,16 +24,17 @@ namespace System.Globalization
         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 };
-        private static readonly double[] s_coefficients1700to1799 = new double[] { 8.118780842, -0.005092142, 0.003336121, -0.0000266484 };
-        private static readonly double[] s_coefficients1620to1699 = new double[] { 196.58333, -4.0675, 0.0219167 };
-        private static readonly double[] s_lambdaCoefficients = new double[] { 280.46645, 36000.76983, 0.0003032 };
-        private static readonly double[] s_anomalyCoefficients = new double[] { 357.52910, 35999.05030, -0.0001559, -0.00000048 };
-        private static readonly double[] s_eccentricityCoefficients = new double[] { 0.016708617, -0.000042037, -0.0000001236 };
+        private static ReadOnlySpan<double> Coefficients1900to1987 => new double[] { -0.00002, 0.000297, 0.025184, -0.181133, 0.553040, -0.861938, 0.677066, -0.212591 };
+        private static ReadOnlySpan<double> 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 };
+        private static ReadOnlySpan<double> Coefficients1700to1799 => new double[] { 8.118780842, -0.005092142, 0.003336121, -0.0000266484 };
+        private static ReadOnlySpan<double> Coefficients1620to1699 => new double[] { 196.58333, -4.0675, 0.0219167 };
+        private static ReadOnlySpan<double> LambdaCoefficients => new double[] { 280.46645, 36000.76983, 0.0003032 };
+        private static ReadOnlySpan<double> AnomalyCoefficients => new double[] { 357.52910, 35999.05030, -0.0001559, -0.00000048 };
+        private static ReadOnlySpan<double> EccentricityCoefficients => new double[] { 0.016708617, -0.000042037, -0.0000001236 };
+        private static ReadOnlySpan<double> CoefficientsA => new double[] { 124.90, -1934.134, 0.002063 };
+        private static ReadOnlySpan<double> CoefficientsB => new double[] { 201.11, 72001.5377, 0.00057 };
+
         private static readonly double[] s_coefficients = new double[] { Angle(23, 26, 21.448), Angle(0, 0, -46.8150), Angle(0, 0, -0.00059), Angle(0, 0, 0.001813) };
-        private static readonly double[] s_coefficientsA = new double[] { 124.90, -1934.134, 0.002063 };
-        private static readonly double[] s_coefficientsB = new double[] { 201.11, 72001.5377, 0.00057 };
 
         private static double RadiansFromDegrees(double degree)
         {
@@ -129,7 +130,7 @@ namespace System.Globalization
             return longitude / FullCircleOfArc;
         }
 
-        private static double PolynomialSum(double[] coefficients, double indeterminate)
+        private static double PolynomialSum(ReadOnlySpan<double> coefficients, double indeterminate)
         {
             double sum = coefficients[0];
             double indeterminateRaised = 1;
@@ -168,28 +169,28 @@ namespace System.Globalization
         {
             Debug.Assert(1900 <= gregorianYear && gregorianYear <= 1987);
             double centuriesFrom1900 = CenturiesFrom1900(gregorianYear);
-            return PolynomialSum(s_coefficients1900to1987, centuriesFrom1900);
+            return PolynomialSum(Coefficients1900to1987, centuriesFrom1900);
         }
 
         private static double EphemerisCorrection1800to1899(int gregorianYear)
         {
             Debug.Assert(1800 <= gregorianYear && gregorianYear <= 1899);
             double centuriesFrom1900 = CenturiesFrom1900(gregorianYear);
-            return PolynomialSum(s_coefficients1800to1899, centuriesFrom1900);
+            return PolynomialSum(Coefficients1800to1899, centuriesFrom1900);
         }
 
         private static double EphemerisCorrection1700to1799(int gregorianYear)
         {
             Debug.Assert(1700 <= gregorianYear && gregorianYear <= 1799);
             double yearsSince1700 = gregorianYear - 1700;
-            return PolynomialSum(s_coefficients1700to1799, yearsSince1700) / SecondsPerDay;
+            return PolynomialSum(Coefficients1700to1799, yearsSince1700) / SecondsPerDay;
         }
 
         private static double EphemerisCorrection1620to1699(int gregorianYear)
         {
             Debug.Assert(1620 <= gregorianYear && gregorianYear <= 1699);
             double yearsSince1600 = gregorianYear - 1600;
-            return PolynomialSum(s_coefficients1620to1699, yearsSince1600) / SecondsPerDay;
+            return PolynomialSum(Coefficients1620to1699, yearsSince1600) / SecondsPerDay;
         }
 
         // ephemeris-correction: correction to account for the slowing down of the rotation of the earth
@@ -233,9 +234,9 @@ namespace System.Globalization
         private static double EquationOfTime(double time)
         {
             double julianCenturies = JulianCenturies(time);
-            double lambda = PolynomialSum(s_lambdaCoefficients, julianCenturies);
-            double anomaly = PolynomialSum(s_anomalyCoefficients, julianCenturies);
-            double eccentricity = PolynomialSum(s_eccentricityCoefficients, julianCenturies);
+            double lambda = PolynomialSum(LambdaCoefficients, julianCenturies);
+            double anomaly = PolynomialSum(AnomalyCoefficients, julianCenturies);
+            double eccentricity = PolynomialSum(EccentricityCoefficients, julianCenturies);
 
             double epsilon = Obliquity(julianCenturies);
             double tanHalfEpsilon = TanOfDegree(epsilon / 2);
@@ -345,8 +346,8 @@ namespace System.Globalization
 
         private static double Nutation(double julianCenturies)
         {
-            double a = PolynomialSum(s_coefficientsA, julianCenturies);
-            double b = PolynomialSum(s_coefficientsB, julianCenturies);
+            double a = PolynomialSum(CoefficientsA, julianCenturies);
+            double b = PolynomialSum(CoefficientsB, julianCenturies);
             return (-0.004778 * SinOfDegree(a)) - (0.0003667 * SinOfDegree(b));
         }
 
index 0294c7c240871c56b6f846532b60c9849dd1cf50..f012ae3b0adf8e33771f7acee3a9e1d1aa84df8b 100644 (file)
@@ -11,9 +11,8 @@ namespace System.Globalization
         private const int nDaysPerMonth = 3;
 
         // # of days so far in the solar year
-        private static readonly int[] s_daysToMonth365 = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
-
-        private static readonly int[] s_daysToMonth366 = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
+        private static ReadOnlySpan<int> DaysToMonth365 => new int[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+        private static ReadOnlySpan<int> DaysToMonth366 => new int[] { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
 
         public override CalendarAlgorithmType AlgorithmType => CalendarAlgorithmType.LunisolarCalendar;
 
@@ -273,7 +272,7 @@ namespace System.Globalization
             int jan1Date;
 
             // Calculate the day number in the solar year.
-            int solarDay = isLeapYear ? s_daysToMonth366[solarMonth - 1] : s_daysToMonth365[solarMonth - 1];
+            int solarDay = isLeapYear ? DaysToMonth366[solarMonth - 1] : DaysToMonth365[solarMonth - 1];
             solarDay += solarDate;
 
             // Calculate the day number in the lunar year.
@@ -314,7 +313,7 @@ namespace System.Globalization
             // part of the lunar year.  since this part is always in Jan or Feb,
             // we don't need to handle Leap Year (LY only affects March
             // and later).
-            lunarDay -= s_daysToMonth365[jan1Month - 1];
+            lunarDay -= DaysToMonth365[jan1Month - 1];
             lunarDay -= (jan1Date - 1);
 
             // convert the lunar day into a lunar month/date
@@ -362,7 +361,7 @@ namespace System.Globalization
 
             // calc the solar day of year of 1 Lunar day
             bool isLeapYear = GregorianIsLeapYear(lunarYear);
-            int[] days = isLeapYear ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<int> days = isLeapYear ? DaysToMonth366 : DaysToMonth365;
 
             solarDay = jan1Date;
 
index ed9bde883abd12ddc52de2b1611e85ee73c280d2..33c61798f8a2c4ab0d4cb1b526f472e68ed1e341 100644 (file)
@@ -22,9 +22,9 @@ namespace System.Globalization
 
         private GregorianCalendarTypes _type;
 
-        private static readonly int[] DaysToMonth365 = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+        internal static ReadOnlySpan<int> DaysToMonth365 => new int[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
 
-        private static readonly int[] DaysToMonth366 = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
+        internal static ReadOnlySpan<int> DaysToMonth366 => new int[] { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
 
         private static volatile Calendar? s_defaultInstance;
 
@@ -96,7 +96,7 @@ namespace System.Globalization
         {
             if (year >= 1 && year <= MaxYear && month >= 1 && month <= 12)
             {
-                int[] days = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
+                ReadOnlySpan<int> days = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
                 if (day >= 1 && (day <= days[month] - days[month - 1]))
                 {
                     int y = year - 1;
@@ -157,7 +157,7 @@ namespace System.Globalization
                 y += (i - 11) / 12;
             }
 
-            int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
+            ReadOnlySpan<int> daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
             int days = (daysArray[m] - daysArray[m - 1]);
 
             if (d > days)
@@ -278,7 +278,7 @@ namespace System.Globalization
                 return false;
             }
 
-            int[] days = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
+            ReadOnlySpan<int> days = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
             return day <= (days[month] - days[month - 1]);
         }
 
index 4054731d261427ecb174ef4dd4b63964b2e354ad..b100b633e9ac0685cd00f225137483e80ce568e2 100644 (file)
@@ -53,16 +53,6 @@ namespace System.Globalization
         //
         internal int MaxYear => m_maxYear;
 
-        internal static readonly int[] DaysToMonth365 =
-        {
-            0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
-        };
-
-        internal static readonly int[] DaysToMonth366 =
-        {
-            0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
-        };
-
         private readonly int m_maxYear;
         private readonly int m_minYear;
         private readonly Calendar m_Cal;
@@ -197,7 +187,7 @@ namespace System.Globalization
         {
             if (year >= 1 && year <= 9999 && month >= 1 && month <= 12)
             {
-                int[] days = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
+                ReadOnlySpan<int> days = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? GregorianCalendar.DaysToMonth366 : GregorianCalendar.DaysToMonth365;
                 if (day >= 1 && (day <= days[month] - days[month - 1]))
                 {
                     int y = year - 1;
@@ -271,7 +261,7 @@ namespace System.Globalization
                 m = 12 + (i + 1) % 12;
                 y += (i - 11) / 12;
             }
-            int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
+            ReadOnlySpan<int> daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? GregorianCalendar.DaysToMonth366 : GregorianCalendar.DaysToMonth365;
             int days = (daysArray[m] - daysArray[m - 1]);
 
             if (d > days)
@@ -338,7 +328,7 @@ namespace System.Globalization
             {
                 ThrowHelper.ThrowArgumentOutOfRange_Month(month);
             }
-            int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366 : DaysToMonth365);
+            ReadOnlySpan<int> days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? GregorianCalendar.DaysToMonth366 : GregorianCalendar.DaysToMonth365);
             return days[month] - days[month - 1];
         }
 
index 3e8345929c9d3c6121a25e002eab619a6be8e0ec..9bededeb7b3b01efe8105bc1ab57105bdd40c297 100644 (file)
@@ -48,7 +48,7 @@ namespace System.Globalization
         private const int MinAdvancedHijri = -2;
         private const int MaxAdvancedHijri = 2;
 
-        private static readonly int[] s_hijriMonthDays = { 0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325, 355 };
+        private static ReadOnlySpan<int> HijriMonthDays => new int[] { 0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325, 355 };
 
         private int _hijriAdvance = int.MinValue;
 
@@ -80,7 +80,7 @@ namespace System.Globalization
 
         private long GetAbsoluteDateHijri(int y, int m, int d)
         {
-            return (long)(DaysUpToHijriYear(y) + s_hijriMonthDays[m - 1] + d - 1 - HijriAdjustment);
+            return (long)(DaysUpToHijriYear(y) + HijriMonthDays[m - 1] + d - 1 - HijriAdjustment);
         }
 
         private long DaysUpToHijriYear(int HijriYear)
@@ -241,7 +241,7 @@ namespace System.Globalization
                 return (int)numDays;
             }
 
-            while ((hijriMonth <= 12) && (numDays > s_hijriMonthDays[hijriMonth - 1]))
+            while ((hijriMonth <= 12) && (numDays > HijriMonthDays[hijriMonth - 1]))
             {
                 hijriMonth++;
             }
@@ -253,7 +253,7 @@ namespace System.Globalization
             }
 
             // Calculate the Hijri Day.
-            int hijriDay = (int)(numDays - s_hijriMonthDays[hijriMonth - 1]);
+            int hijriDay = (int)(numDays - HijriMonthDays[hijriMonth - 1]);
 
             if (part == DatePartDay)
             {
index 4ca862777f19373a4d1e667fa6e5f386c9e66b9b..b7c4d1b0cf27faf3068ebb6e031895a263f1dcd2 100644 (file)
@@ -24,10 +24,10 @@ namespace System.Globalization
         internal const int DoubleCommaSep = 4 << 4;
 
         private const int CulturesCount = 864;
-        // s_nameIndexToNumericData is mapping from index in s_localeNamesIndices to locale data.
+        // NameIndexToNumericData is mapping from index in s_localeNamesIndices to locale data.
         // each row in the table will have the following data:
         //      Lcid, Ansi codepage, Oem codepage, MAC codepage, EBCDIC codepage, Geo Id, Digit Substitution | ListSeparator, specific locale index, Console locale index
-        private static readonly int[] s_nameIndexToNumericData = new int[CulturesCount * NUMERIC_LOCALE_DATA_COUNT_PER_ROW]
+        private static ReadOnlySpan<int> NameIndexToNumericData => new int[CulturesCount * NUMERIC_LOCALE_DATA_COUNT_PER_ROW]
         {
             // Lcid,  Ansi CP, Oem CP, MAC CP, EBCDIC CP, Geo Id, digit substitution | ListSeparator, Specific culture index, Console locale index  // index - locale name
             0x1000 , 0x0   , 0x1   , 0x2   , 0x1f4 , 0x49  , 1 | SemicolonSep      , 3   , 240 , // 0    - aa
@@ -1327,20 +1327,20 @@ namespace System.Globalization
             Console.WriteLine("private static ReadOnlySpan<byte> LcidToCultureNameIndices => new byte[CulturesCount * NumericLocaleDataBytesPerRow]");
             Console.WriteLine("{");
 
-            for (int i = 0; i < s_nameIndexToNumericData.Length; i += NUMERIC_LOCALE_DATA_COUNT_PER_ROW)
+            for (int i = 0; i < NameIndexToNumericData.Length; i += NUMERIC_LOCALE_DATA_COUNT_PER_ROW)
             {
-                uint Lcid = (uint)s_nameIndexToNumericData[i];
-                uint AnsiCP = (uint)s_nameIndexToNumericData[i + 1];
-                uint OemCP = (uint)s_nameIndexToNumericData[i + 2];
-                uint MacCP = (uint)s_nameIndexToNumericData[i + 3];
-                uint EBCDIC = (uint)s_nameIndexToNumericData[i + 4];
-                uint GeoId = (uint)s_nameIndexToNumericData[i + 5];
-                uint DigitList = (uint)s_nameIndexToNumericData[i + 6];
+                uint Lcid = (uint)NameIndexToNumericData[i];
+                uint AnsiCP = (uint)NameIndexToNumericData[i + 1];
+                uint OemCP = (uint)NameIndexToNumericData[i + 2];
+                uint MacCP = (uint)NameIndexToNumericData[i + 3];
+                uint EBCDIC = (uint)NameIndexToNumericData[i + 4];
+                uint GeoId = (uint)NameIndexToNumericData[i + 5];
+                uint DigitList = (uint)NameIndexToNumericData[i + 6];
 
-                int index = s_nameIndexToNumericData[i + 7];
+                int index = NameIndexToNumericData[i + 7];
                 Debug.Assert(index == -1 || index < 0xfff);
                 uint SpecificCultureIndex = index == -1 ? 0xfff: (uint)index;
-                index = s_nameIndexToNumericData[i + 8];
+                index = NameIndexToNumericData[i + 8];
                 Debug.Assert(index == -1 || index < 0xfff);
                 uint ConsoleLocaleIndex = index == -1 ? 0xfff : (uint)index;
 
index 4edc8cbce6f400af2da08a79f9fabe3bdf17da19..0db8614f24858d27f6011ae0db2148ee0338234c 100644 (file)
@@ -31,16 +31,6 @@ namespace System.Globalization
         // Number of days in 4 years
         private const int JulianDaysPer4Years = JulianDaysPerYear * 4 + 1;
 
-        private static readonly int[] s_daysToMonth365 =
-        {
-            0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
-        };
-
-        private static readonly int[] s_daysToMonth366 =
-        {
-            0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
-        };
-
         // Gregorian Calendar 9999/12/31 = Julian Calendar 9999/10/19
         // keep it as variable field for serialization compat.
         internal int MaxYear = 9999;
@@ -106,7 +96,7 @@ namespace System.Globalization
             }
 
             bool isLeapYear = (year % 4) == 0;
-            int[] days = isLeapYear ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<int> days = isLeapYear ? GregorianCalendar.DaysToMonth366 : GregorianCalendar.DaysToMonth365;
             int monthDays = days[month] - days[month - 1];
             if (day < 1 || day > monthDays)
             {
@@ -153,7 +143,7 @@ namespace System.Globalization
             // Leap year calculation looks different from IsLeapYear since y1, y4,
             // and y100 are relative to year 1, not year 0
             bool leapYear = (y1 == 3);
-            int[] days = leapYear ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<int> days = leapYear ? GregorianCalendar.DaysToMonth366 : GregorianCalendar.DaysToMonth365;
             // All months have less than 32 days, so n >> 5 is a good conservative
             // estimate for the month
             int m = (n >> 5) + 1;
@@ -178,7 +168,7 @@ namespace System.Globalization
         /// </summary>
         internal static long DateToTicks(int year, int month, int day)
         {
-            int[] days = (year % 4 == 0) ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<int> days = (year % 4 == 0) ? GregorianCalendar.DaysToMonth366 : GregorianCalendar.DaysToMonth365;
             int y = year - 1;
             int n = y * 365 + y / 4 + days[month - 1] + day - 1;
             // Gregorian 1/1/0001 is Julian 1/3/0001. n * TicksPerDay is the ticks in JulianCalendar.
@@ -212,7 +202,7 @@ namespace System.Globalization
                 y += (i - 11) / 12;
             }
 
-            int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<int> daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? GregorianCalendar.DaysToMonth366 : GregorianCalendar.DaysToMonth365;
             int days = daysArray[m] - daysArray[m - 1];
             if (d > days)
             {
@@ -245,7 +235,7 @@ namespace System.Globalization
         {
             CheckYearEraRange(year, era);
             CheckMonthRange(month);
-            int[] days = (year % 4 == 0) ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<int> days = (year % 4 == 0) ? GregorianCalendar.DaysToMonth366 : GregorianCalendar.DaysToMonth365;
             return days[month] - days[month - 1];
         }
 
index b69ac8e7deb1ede7bbfe6fd11c5316971e1c8b07..d4a93276b5159afab18211f11f58cf98690a65eb 100644 (file)
@@ -30,7 +30,7 @@ namespace System.Globalization
         private const int DatePartDay = 3;
         private const int MonthsPerYear = 12;
 
-        private static readonly int[] s_daysToMonth = { 0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336, 366 };
+        private static ReadOnlySpan<int> DaysToMonth => new int[] { 0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336, 366 };
 
         private const int MaxCalendarYear = 9378;
         private const int MaxCalendarMonth = 10;
@@ -125,7 +125,7 @@ namespace System.Globalization
         {
             Debug.Assert(ordinalDay <= 366);
             int index = 0;
-            while (ordinalDay > s_daysToMonth[index])
+            while (ordinalDay > DaysToMonth[index])
             {
                 index++;
             }
@@ -138,7 +138,7 @@ namespace System.Globalization
             Debug.Assert(1 <= month && month <= 12);
             // months are one based but for calculations use 0 based
             --month;
-            return s_daysToMonth[month];
+            return DaysToMonth[month];
         }
 
         internal int GetDatePart(long ticks, int part)
@@ -276,7 +276,7 @@ namespace System.Globalization
                 return MaxCalendarDay;
             }
 
-            int daysInMonth = s_daysToMonth[month] - s_daysToMonth[month - 1];
+            int daysInMonth = DaysToMonth[month] - DaysToMonth[month - 1];
             if ((month == MonthsPerYear) && !IsLeapYear(year))
             {
                 Debug.Assert(daysInMonth == 30);
@@ -291,7 +291,7 @@ namespace System.Globalization
             CheckYearRange(year, era);
             if (year == MaxCalendarYear)
             {
-                return s_daysToMonth[MaxCalendarMonth - 1] + MaxCalendarDay;
+                return DaysToMonth[MaxCalendarMonth - 1] + MaxCalendarDay;
             }
 
             return IsLeapYear(year, CurrentEra) ? 366 : 365;
index c1cb1610c01aaacdecbbbbf1d3b3dcd31cfab0a7..5c7252bfefffe349898c71af15cb80ffb6ac1266 100644 (file)
@@ -38,7 +38,7 @@ namespace System
         private const double doubleRoundLimit = 1e16d;
 
         // This table is required for the Round function which can specify the number of digits to round to
-        private static readonly double[] roundPower10Double = new double[] {
+        private static ReadOnlySpan<double> RoundPower10Double => new double[] {
           1E0, 1E1, 1E2, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8,
           1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15
         };
@@ -1347,7 +1347,7 @@ namespace System
 
             if (Abs(value) < doubleRoundLimit)
             {
-                double power10 = roundPower10Double[digits];
+                double power10 = RoundPower10Double[digits];
 
                 value *= power10;
 
index 90a5f84af6603c30f870a37e611a80f49bbadf9e..31ae24f93e92d174805e80e1750cbeccf383f9bc 100644 (file)
@@ -31,7 +31,7 @@ namespace System
         private const int maxRoundingDigits = 6;
 
         // This table is required for the Round function which can specify the number of digits to round to
-        private static readonly float[] roundPower10Single = new float[] {
+        private static ReadOnlySpan<float> RoundPower10Single => new float[] {
             1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f
         };
 
@@ -463,7 +463,7 @@ namespace System
 
             if (Abs(x) < singleRoundLimit)
             {
-                float power10 = roundPower10Single[digits];
+                float power10 = RoundPower10Single[digits];
 
                 x *= power10;
 
index f7e613f9628298f945db1f8e9266dd6d135546d4..aba4b814fc399a3fe650dce84edcc6fbcd1937aa 100644 (file)
@@ -33,7 +33,7 @@ namespace System
             private const int BitsPerBlock = sizeof(int) * 8;
             private const int MaxBlockCount = (MaxBits + (BitsPerBlock - 1)) / BitsPerBlock;
 
-            private static readonly uint[] s_Pow10UInt32Table = new uint[]
+            private static ReadOnlySpan<uint> Pow10UInt32Table => new uint[]
             {
                 1,          // 10^0
                 10,         // 10^1
@@ -48,7 +48,7 @@ namespace System
                 1000000000  // 10^9
             };
 
-            private static readonly int[] s_Pow10BigNumTableIndices = new int[]
+            private static ReadOnlySpan<int> Pow10BigNumTableIndices => new int[]
             {
                 0,          // 10^8
                 2,          // 10^16
@@ -60,7 +60,7 @@ namespace System
                 116,        // 10^1024
             };
 
-            private static readonly uint[] s_Pow10BigNumTable = new uint[]
+            private static ReadOnlySpan<uint> Pow10BigNumTable => new uint[]
             {
                 // 10^8
                 1,          // _length
@@ -832,37 +832,37 @@ namespace System
 
             public static void Pow10(uint exponent, out BigInteger result)
             {
-                // We leverage two arrays - s_Pow10UInt32Table and s_Pow10BigNumTable to speed up the Pow10 calculation.
+                // We leverage two arrays - Pow10UInt32Table and Pow10BigNumTable to speed up the Pow10 calculation.
                 //
-                // s_Pow10UInt32Table stores the results of 10^0 to 10^7.
-                // s_Pow10BigNumTable stores the results of 10^8, 10^16, 10^32, 10^64, 10^128, 10^256, and 10^512
+                // Pow10UInt32Table stores the results of 10^0 to 10^7.
+                // Pow10BigNumTable stores the results of 10^8, 10^16, 10^32, 10^64, 10^128, 10^256, and 10^512
                 //
                 // For example, let's say exp = 0b111111. We can split the exp to two parts, one is small exp,
                 // which 10^smallExp can be represented as uint, another part is 10^bigExp, which must be represented as BigNum.
                 // So the result should be 10^smallExp * 10^bigExp.
                 //
-                // Calculating 10^smallExp is simple, we just lookup the 10^smallExp from s_Pow10UInt32Table.
+                // Calculating 10^smallExp is simple, we just lookup the 10^smallExp from Pow10UInt32Table.
                 // But here's a bad news: although uint can represent 10^9, exp 9's binary representation is 1001.
                 // That means 10^(1011), 10^(1101), 10^(1111) all cannot be stored as uint, we cannot easily say something like:
-                // "Any bits <= 3 is small exp, any bits > 3 is big exp". So instead of involving 10^8, 10^9 to s_Pow10UInt32Table,
-                // consider 10^8 and 10^9 as a bigNum, so they fall into s_Pow10BigNumTable. Now we can have a simple rule:
+                // "Any bits <= 3 is small exp, any bits > 3 is big exp". So instead of involving 10^8, 10^9 to Pow10UInt32Table,
+                // consider 10^8 and 10^9 as a bigNum, so they fall into Pow10BigNumTable. Now we can have a simple rule:
                 // "Any bits <= 3 is small exp, any bits > 3 is big exp".
                 //
                 // For 0b111111, we first calculate 10^(smallExp), which is 10^(7), now we can shift right 3 bits, prepare to calculate the bigExp part,
                 // the exp now becomes 0b000111.
                 //
-                // Apparently the lowest bit of bigExp should represent 10^8 because we have already shifted 3 bits for smallExp, so s_Pow10BigNumTable[0] = 10^8.
+                // Apparently the lowest bit of bigExp should represent 10^8 because we have already shifted 3 bits for smallExp, so Pow10BigNumTable[0] = 10^8.
                 // Now let's shift exp right 1 bit, the lowest bit should represent 10^(8 * 2) = 10^16, and so on...
                 //
-                // That's why we just need the values of s_Pow10BigNumTable be power of 2.
+                // That's why we just need the values of Pow10BigNumTable be power of 2.
                 //
                 // More details of this implementation can be found at: https://github.com/dotnet/coreclr/pull/12894#discussion_r128890596
 
-                // Validate that `s_Pow10BigNumTable` has exactly enough trailing elements to fill a BigInteger (which contains MaxBlockCount + 1 elements)
+                // Validate that `Pow10BigNumTable` has exactly enough trailing elements to fill a BigInteger (which contains MaxBlockCount + 1 elements)
                 // We validate here, since this is the only current consumer of the array
-                Debug.Assert((s_Pow10BigNumTableIndices[^1] + MaxBlockCount + 2) == s_Pow10BigNumTable.Length);
+                Debug.Assert((Pow10BigNumTableIndices[^1] + MaxBlockCount + 2) == Pow10BigNumTable.Length);
 
-                SetUInt32(out BigInteger temp1, s_Pow10UInt32Table[exponent & 0x7]);
+                SetUInt32(out BigInteger temp1, Pow10UInt32Table[(int)(exponent & 0x7)]);
                 ref BigInteger lhs = ref temp1;
 
                 SetZero(out BigInteger temp2);
@@ -877,7 +877,7 @@ namespace System
                     if ((exponent & 1) != 0)
                     {
                         // Multiply into the next temporary
-                        fixed (uint* pBigNumEntry = &s_Pow10BigNumTable[s_Pow10BigNumTableIndices[index]])
+                        fixed (uint* pBigNumEntry = &Pow10BigNumTable[Pow10BigNumTableIndices[(int)index]])
                         {
                             ref BigInteger rhs = ref *(BigInteger*)(pBigNumEntry);
                             Multiply(ref lhs, ref rhs, out product);
@@ -1084,7 +1084,7 @@ namespace System
             {
                 if (exponent <= 9)
                 {
-                    Multiply(s_Pow10UInt32Table[exponent]);
+                    Multiply(Pow10UInt32Table[(int)exponent]);
                 }
                 else if (!IsZero())
                 {
index 2ff9d28e868572365e7fb9ff51eba0f197139953..b12e4a42263b29e9603a0629b502f20ccebcc45f 100644 (file)
@@ -34,7 +34,7 @@ namespace System
             private const int MaximalTargetExponent = -32;
             private const int MinimalTargetExponent = -60;
 
-            private static readonly short[] s_CachedPowersBinaryExponent = new short[]
+            private static ReadOnlySpan<short> CachedPowersBinaryExponent => new short[]
             {
                 -1220,
                 -1193,
@@ -125,7 +125,7 @@ namespace System
                 1066,
             };
 
-            private static readonly short[] s_CachedPowersDecimalExponent = new short[]
+            private static ReadOnlySpan<short> CachedPowersDecimalExponent => new short[]
             {
                 CachedPowersMinDecimalExponent,
                 -340,
@@ -216,7 +216,7 @@ namespace System
                 CachedPowersPowerMaxDecimalExponent,
             };
 
-            private static readonly ulong[] s_CachedPowersSignificand = new ulong[]
+            private static ReadOnlySpan<ulong> CachedPowersSignificand => new ulong[]
             {
                 0xFA8FD5A0081C0288,
                 0xBAAEE17FA23EBF76,
@@ -307,7 +307,7 @@ namespace System
                 0xAF87023B9BF0EE6B,
             };
 
-            private static readonly uint[] s_SmallPowersOfTen = new uint[]
+            private static ReadOnlySpan<uint> SmallPowersOfTen => new uint[]
             {
                 1,          // 10^0
                 10,         // 10^1
@@ -540,15 +540,15 @@ namespace System
 
                 // 1233/4096 is approximately 1/log2(10)
                 int exponentGuess = ((numberBits + 1) * 1233) >> 12;
-                Debug.Assert((uint)(exponentGuess) < s_SmallPowersOfTen.Length);
+                Debug.Assert((uint)(exponentGuess) < SmallPowersOfTen.Length);
 
-                uint power = s_SmallPowersOfTen[exponentGuess];
+                uint power = SmallPowersOfTen[exponentGuess];
 
                 // We don't have any guarantees that 2^numberBits <= number
                 if (number < power)
                 {
                     exponentGuess--;
-                    power = s_SmallPowersOfTen[exponentGuess];
+                    power = SmallPowersOfTen[exponentGuess];
                 }
 
                 exponentPlusOne = exponentGuess + 1;
@@ -606,7 +606,7 @@ namespace System
                 //      If requestedDigits >= 11, integrals is not able to exhaust the count by itself since 10^(11 -1) > uint.MaxValue >= integrals.
                 //      If integrals < 10^(requestedDigits - 1), integrals cannot exhaust the count.
                 //      Otherwise, integrals might be able to exhaust the count and we need to execute the rest of the code.
-                if ((fractionals == 0) && ((requestedDigits >= 11) || (integrals < s_SmallPowersOfTen[requestedDigits - 1])))
+                if ((fractionals == 0) && ((requestedDigits >= 11) || (integrals < SmallPowersOfTen[requestedDigits - 1])))
                 {
                     Debug.Assert(buffer[0] == '\0');
                     length = 0;
@@ -884,19 +884,19 @@ namespace System
             // Returns a cached power-of-ten with a binary exponent in the range [minExponent; maxExponent] (boundaries included).
             private static DiyFp GetCachedPowerForBinaryExponentRange(int minExponent, int maxExponent, out int decimalExponent)
             {
-                Debug.Assert(s_CachedPowersSignificand.Length == s_CachedPowersBinaryExponent.Length);
-                Debug.Assert(s_CachedPowersSignificand.Length == s_CachedPowersDecimalExponent.Length);
+                Debug.Assert(CachedPowersSignificand.Length == CachedPowersBinaryExponent.Length);
+                Debug.Assert(CachedPowersSignificand.Length == CachedPowersDecimalExponent.Length);
 
                 double k = Math.Ceiling((minExponent + DiyFp.SignificandSize - 1) * D1Log210);
                 int index = ((CachedPowersOffset + (int)(k) - 1) / CachedPowersDecimalExponentDistance) + 1;
 
-                Debug.Assert((uint)(index) < s_CachedPowersSignificand.Length);
+                Debug.Assert((uint)(index) < CachedPowersSignificand.Length);
 
-                Debug.Assert(minExponent <= s_CachedPowersBinaryExponent[index]);
-                Debug.Assert(s_CachedPowersBinaryExponent[index] <= maxExponent);
+                Debug.Assert(minExponent <= CachedPowersBinaryExponent[index]);
+                Debug.Assert(CachedPowersBinaryExponent[index] <= maxExponent);
 
-                decimalExponent = s_CachedPowersDecimalExponent[index];
-                return new DiyFp(s_CachedPowersSignificand[index], s_CachedPowersBinaryExponent[index]);
+                decimalExponent = CachedPowersDecimalExponent[index];
+                return new DiyFp(CachedPowersSignificand[index], CachedPowersBinaryExponent[index]);
             }
 
             // Rounds the buffer upwards if the result is closer to v by possibly adding 1 to the buffer.
index bec85ff737bab65ecaade80a0165990841fdf09f..58bb1ebfc57240bd7d7f0268b15f5e5f283c54c4 100644 (file)
@@ -140,7 +140,7 @@ namespace System
         /// Normalized 128 bits values for powers of 5^q for q in range [-342, 308]
         /// stored as 2 64-bits integers for convenience
         /// </summary>
-        private static readonly ulong[] s_Pow5128Table = {
+        private static ReadOnlySpan<ulong> Pow5128Table => new ulong[] {
             0xeef453d6923bd65a, 0x113faa2906a13b3f,
             0x9558b4661b6565f8, 0x4ac7ca59a424c507,
             0xbaaee17fa23ebf76, 0x5d79bcf00d2df649,
@@ -1647,13 +1647,13 @@ namespace System
             int index = 2 * (int)(q - -342);
             // For small values of q, e.g., q in [0,27], the answer is always exact because
             // Math.BigMul gives the exact answer.
-            ulong high = Math.BigMul(w, s_Pow5128Table[index], out ulong low);
+            ulong high = Math.BigMul(w, Pow5128Table[index], out ulong low);
             ulong precisionMask = (bitPrecision < 64) ? (0xFFFFFFFFFFFFFFFFUL >> bitPrecision) : 0xFFFFFFFFFFFFFFFFUL;
             if ((high & precisionMask) == precisionMask)
             {
                 // could further guard with  (lower + w < lower)
                 // regarding the second product, we only need secondproduct.high, but our expectation is that the compiler will optimize this extra work away if needed.
-                ulong high2 = Math.BigMul(w, s_Pow5128Table[index + 1], out ulong _);
+                ulong high2 = Math.BigMul(w, Pow5128Table[index + 1], out ulong _);
                 low += high2;
                 if (high2 > low)
                 {
index c110074189c19ee65799f17608f924f62b4330a6..fe856d6148225bed7190b713ad75bd19923d3042 100644 (file)
@@ -6,7 +6,7 @@ namespace System.Text
     internal sealed partial class EncoderLatin1BestFitFallbackBuffer
     {
         // Best fit for ASCII, and since it works for ASCII, we use it for latin1 as well.
-        private static readonly char[] s_arrayCharBestFit =
+        private static ReadOnlySpan<char> ArrayCharBestFit => new char[]
         {
 // The first many are in case you wanted to use this for ASCIIEncoding, which we don't need to do any more.
 //          (char)0x00a0, (char)0x0020,    // No-Break Space -> Space
index 8fb9515001842a5e3450b66d14547807899eec87..d9ceb1178643e0ec4ceabb3895314b75fc5c4d7b 100644 (file)
@@ -123,8 +123,7 @@ namespace System.Text
         {
             // Need to figure out our best fit character, low is beginning of array, high is 1 AFTER end of array
             int lowBound = 0;
-            Debug.Assert(s_arrayCharBestFit != null);
-            int highBound = s_arrayCharBestFit.Length;
+            int highBound = ArrayCharBestFit.Length;
             int index;
 
             // Binary search the array
@@ -136,13 +135,13 @@ namespace System.Text
                 // Also note that index can never == highBound (because diff is rounded down)
                 index = ((iDiff / 2) + lowBound) & 0xFFFE;
 
-                char cTest = s_arrayCharBestFit[index];
+                char cTest = ArrayCharBestFit[index];
                 if (cTest == cUnknown)
                 {
                     // We found it
-                    Debug.Assert(index + 1 < s_arrayCharBestFit.Length,
+                    Debug.Assert(index + 1 < ArrayCharBestFit.Length,
                         "[EncoderLatin1BestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array");
-                    return s_arrayCharBestFit[index + 1];
+                    return ArrayCharBestFit[index + 1];
                 }
                 else if (cTest < cUnknown)
                 {
@@ -158,12 +157,12 @@ namespace System.Text
 
             for (index = lowBound; index < highBound; index += 2)
             {
-                if (s_arrayCharBestFit[index] == cUnknown)
+                if (ArrayCharBestFit[index] == cUnknown)
                 {
                     // We found it
-                    Debug.Assert(index + 1 < s_arrayCharBestFit.Length,
+                    Debug.Assert(index + 1 < ArrayCharBestFit.Length,
                         "[EncoderLatin1BestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array");
-                    return s_arrayCharBestFit[index + 1];
+                    return ArrayCharBestFit[index + 1];
                 }
             }
 
index 992891ff08836802cd02661bb37db42bbae61835..2b621d6bce9fe1970a151164d8429c4e2b1715bf 100644 (file)
@@ -9,14 +9,14 @@ namespace System.Text
     internal static partial class EncodingTable
     {
         //
-        // s_encodingNames is the concatenation of all supported IANA names for each codepage.
+        // EncodingNames is the concatenation of all supported IANA names for each codepage.
         // This is done rather than using a large readonly array of strings to avoid
         // generating a large amount of code in the static constructor.
-        // Using indices from s_encodingNamesIndices, we binary search this string when mapping
+        // Using indices from EncodingNamesIndices, we binary search this string when mapping
         // an encoding name to a codepage. Note that these names are all lowercase and are
         // sorted alphabetically.
         //
-        private const string s_encodingNames =
+        private const string EncodingNames =
             "ansi_x3.4-1968" + // 20127
             "ansi_x3.4-1986" + // 20127
             "ascii" + // 20127
@@ -61,11 +61,11 @@ namespace System.Text
             "x-unicode-2-0-utf-8"; // 65001
 
         //
-        // s_encodingNameIndices contains the start index of every encoding name in the string
-        // s_encodingNames. We infer the length of each string by looking at the start index
+        // EncodingNameIndices contains the start index of every encoding name in the string
+        // EncodingNames. We infer the length of each string by looking at the start index
         // of the next string.
         //
-        private static readonly int[] s_encodingNameIndices = new int[]
+        private static ReadOnlySpan<int> EncodingNameIndices => new int[]
         {
             0, // ansi_x3.4-1968 (20127)
             14, // ansi_x3.4-1986 (20127)
@@ -113,13 +113,13 @@ namespace System.Text
         };
 
         //
-        // s_codePagesByName contains the list of supported codepages which match the encoding
-        // names listed in s_encodingNames. The way mapping works is we binary search
-        // s_encodingNames using s_encodingNamesIndices until we find a match for a given name.
-        // The index of the entry in s_encodingNamesIndices will be the index of codepage in
-        // s_codePagesByName.
+        // CodePagesByName contains the list of supported codepages which match the encoding
+        // names listed in EncodingNames. The way mapping works is we binary search
+        // EncodingNames using EncodingNamesIndices until we find a match for a given name.
+        // The index of the entry in EncodingNamesIndices will be the index of codepage in
+        // CodePagesByName.
         //
-        private static readonly ushort[] s_codePagesByName = new ushort[]
+        private static ReadOnlySpan<ushort> CodePagesByName => new ushort[]
         {
             20127, // ansi_x3.4-1968
             20127, // ansi_x3.4-1986
@@ -168,14 +168,14 @@ namespace System.Text
         //
         // When retrieving the value for System.Text.Encoding.WebName or
         // System.Text.Encoding.EncodingName given System.Text.Encoding.CodePage,
-        // we perform a linear search on s_mappedCodePages to find the index of the
+        // we perform a linear search on MappedCodePages to find the index of the
         // given codepage. This is used to index WebNameIndices to get the start
         // index of the web name in the string WebNames, and to index
-        // s_englishNameIndices to get the start of the English name in
-        // s_englishNames. In addition, this arrays indices correspond to the indices
-        // into s_uiFamilyCodePages and s_flags.
+        // EnglishNameIndices to get the start of the English name in
+        // EnglishNames. In addition, this arrays indices correspond to the indices
+        // into UiFamilyCodePages and Flags.
         //
-        private static readonly ushort[] s_mappedCodePages = new ushort[]
+        private static ReadOnlySpan<ushort> MappedCodePages => new ushort[]
         {
             1200, // utf-16
             1201, // utf-16be
@@ -188,9 +188,9 @@ namespace System.Text
         };
 
         //
-        // s_uiFamilyCodePages is indexed by the corresponding index in s_mappedCodePages.
+        // UiFamilyCodePages is indexed by the corresponding index in MappedCodePages.
         //
-        private static readonly int[] s_uiFamilyCodePages = new int[]
+        private static ReadOnlySpan<int> UiFamilyCodePages => new int[]
         {
             1200,
             1200,
@@ -203,13 +203,13 @@ namespace System.Text
         };
 
         //
-        // s_webNames is a concatenation of the default encoding names
+        // WebNames is a concatenation of the default encoding names
         // for each code page. It is used in retrieving the value for
         // System.Text.Encoding.WebName given System.Text.Encoding.CodePage.
         // This is done rather than using a large readonly array of strings to avoid
         // generating a large amount of code in the static constructor.
         //
-        private const string s_webNames =
+        private const string WebNames =
             "utf-16" + // 1200
             "utf-16BE" + // 1201
             "utf-32" + // 12000
@@ -220,11 +220,11 @@ namespace System.Text
             "utf-8"; // 65001
 
         //
-        // s_webNameIndices contains the start index of each code page's default
-        // web name in the string s_webNames. It is indexed by an index into
-        // s_mappedCodePages.
+        // WebNameIndices contains the start index of each code page's default
+        // web name in the string WebNames. It is indexed by an index into
+        // MappedCodePages.
         //
-        private static readonly int[] s_webNameIndices = new int[]
+        private static ReadOnlySpan<int> WebNameIndices => new int[]
         {
             0, // utf-16 (1200)
             6, // utf-16be (1201)
@@ -238,13 +238,13 @@ namespace System.Text
         };
 
         //
-        // s_englishNames is the concatenation of the English names for each codepage.
+        // EnglishNames is the concatenation of the English names for each codepage.
         // It is used in retrieving the value for System.Text.Encoding.EncodingName
         // given System.Text.Encoding.CodePage.
         // This is done rather than using a large readonly array of strings to avoid
         // generating a large amount of code in the static constructor.
         //
-        private const string s_englishNames =
+        private const string EnglishNames =
             "Unicode" + // 1200
             "Unicode (Big-Endian)" + // 1201
             "Unicode (UTF-32)" + // 12000
@@ -255,11 +255,11 @@ namespace System.Text
             "Unicode (UTF-8)"; // 65001
 
         //
-        // s_englishNameIndices contains the start index of each code page's English
-        // name in the string s_englishNames. It is indexed by an index into
-        // s_mappedCodePages.
+        // EnglishNameIndices contains the start index of each code page's English
+        // name in the string EnglishNames. It is indexed by an index into
+        // MappedCodePages.
         //
-        private static readonly int[] s_englishNameIndices = new int[]
+        private static ReadOnlySpan<int> EnglishNameIndices => new int[]
         {
             0, // Unicode (1200)
             7, // Unicode (Big-Endian) (1201)
@@ -278,8 +278,8 @@ namespace System.Text
         private const uint MIMECONTF_SAVABLE_MAILNEWS = Encoding.MIMECONTF_SAVABLE_MAILNEWS;
         private const uint MIMECONTF_SAVABLE_BROWSER = Encoding.MIMECONTF_SAVABLE_BROWSER;
 
-        // s_flags is indexed by the corresponding index in s_mappedCodePages.
-        private static readonly uint[] s_flags = new uint[]
+        // Flags is indexed by the corresponding index in MappedCodePages.
+        private static ReadOnlySpan<uint> Flags => new uint[]
         {
             MIMECONTF_SAVABLE_BROWSER,
             0,
index ded8d29edc76c4704605536029472198f2e693de..e404065b099bb97598c9907b499b02137e6dd761 100644 (file)
@@ -50,12 +50,12 @@ namespace System.Text
         private static int InternalGetCodePageFromName(string name)
         {
             int left = 0;
-            int right = s_encodingNameIndices.Length - 2;
+            int right = EncodingNameIndices.Length - 2;
             int index;
             int result;
 
-            Debug.Assert(s_encodingNameIndices.Length == s_codePagesByName.Length + 1);
-            Debug.Assert(s_encodingNameIndices[^1] == s_encodingNames.Length);
+            Debug.Assert(EncodingNameIndices.Length == CodePagesByName.Length + 1);
+            Debug.Assert(EncodingNameIndices[^1] == EncodingNames.Length);
 
             ReadOnlySpan<char> invariantName = name.ToLowerInvariant().AsSpan();
 
@@ -65,13 +65,13 @@ namespace System.Text
             {
                 index = ((right - left) / 2) + left;
 
-                Debug.Assert(index < s_encodingNameIndices.Length - 1);
-                result = string.CompareOrdinal(invariantName, s_encodingNames.AsSpan(s_encodingNameIndices[index], s_encodingNameIndices[index + 1] - s_encodingNameIndices[index]));
+                Debug.Assert(index < EncodingNameIndices.Length - 1);
+                result = string.CompareOrdinal(invariantName, EncodingNames.AsSpan(EncodingNameIndices[index], EncodingNameIndices[index + 1] - EncodingNameIndices[index]));
 
                 if (result == 0)
                 {
                     // We found the item, return the associated codePage.
-                    return s_codePagesByName[index];
+                    return CodePagesByName[index];
                 }
                 else if (result < 0)
                 {
@@ -88,10 +88,10 @@ namespace System.Text
             // Walk the remaining elements (it'll be 3 or fewer).
             for (; left <= right; left++)
             {
-                Debug.Assert(left < s_encodingNameIndices.Length - 1);
-                if (string.CompareOrdinal(invariantName, s_encodingNames.AsSpan(s_encodingNameIndices[left], s_encodingNameIndices[left + 1] - s_encodingNameIndices[left])) == 0)
+                Debug.Assert(left < EncodingNameIndices.Length - 1);
+                if (string.CompareOrdinal(invariantName, EncodingNames.AsSpan(EncodingNameIndices[left], EncodingNameIndices[left + 1] - EncodingNameIndices[left])) == 0)
                 {
-                    return s_codePagesByName[left];
+                    return CodePagesByName[left];
                 }
             }
 
@@ -107,10 +107,10 @@ namespace System.Text
             // If UTF-7 encoding is not enabled, we adjust the return array length by -1
             // to account for the skipped EncodingInfo element.
 
-            ushort[] mappedCodePages = s_mappedCodePages;
+            ReadOnlySpan<ushort> mappedCodePages = MappedCodePages;
             EncodingInfo[] arrayEncodingInfo = new EncodingInfo[(LocalAppContextSwitches.EnableUnsafeUTF7Encoding) ? mappedCodePages.Length : (mappedCodePages.Length - 1)];
-            string webNames = s_webNames;
-            int[] webNameIndices = s_webNameIndices;
+            string webNames = WebNames;
+            ReadOnlySpan<int> webNameIndices = WebNameIndices;
             int arrayEncodingInfoIdx = 0;
 
             for (int i = 0; i < mappedCodePages.Length; i++)
@@ -135,9 +135,9 @@ namespace System.Text
         internal static EncodingInfo[] GetEncodings(Dictionary<int, EncodingInfo> encodingInfoList)
         {
             Debug.Assert(encodingInfoList != null);
-            ushort[] mappedCodePages = s_mappedCodePages;
-            string webNames = s_webNames;
-            int[] webNameIndices = s_webNameIndices;
+            ReadOnlySpan<ushort> mappedCodePages = MappedCodePages;
+            string webNames = WebNames;
+            ReadOnlySpan<int> webNameIndices = WebNameIndices;
 
             for (int i = 0; i < mappedCodePages.Length; i++)
             {
@@ -177,10 +177,10 @@ namespace System.Text
         {
             if (s_codePageToCodePageData == null)
             {
-                Interlocked.CompareExchange<CodePageDataItem?[]?>(ref s_codePageToCodePageData, new CodePageDataItem[s_mappedCodePages.Length], null);
+                Interlocked.CompareExchange<CodePageDataItem?[]?>(ref s_codePageToCodePageData, new CodePageDataItem[MappedCodePages.Length], null);
             }
 
-            // Keep in sync with s_mappedCodePages
+            // Keep in sync with MappedCodePages
             int index;
             switch (codePage)
             {
@@ -224,13 +224,13 @@ namespace System.Text
 
         private static CodePageDataItem InternalGetCodePageDataItem(int codePage, int index)
         {
-            int uiFamilyCodePage = s_uiFamilyCodePages[index];
-            string webName = s_webNames[s_webNameIndices[index]..s_webNameIndices[index + 1]];
+            int uiFamilyCodePage = UiFamilyCodePages[index];
+            string webName = WebNames[WebNameIndices[index]..WebNameIndices[index + 1]];
             // All supported code pages have identical header names, and body names.
             string headerName = webName;
             string bodyName = webName;
             string displayName = GetDisplayName(codePage, index);
-            uint flags = s_flags[index];
+            uint flags = Flags[index];
 
             return new CodePageDataItem(uiFamilyCodePage, webName, headerName, bodyName, displayName, flags);
         }
@@ -239,7 +239,7 @@ namespace System.Text
         {
             string? displayName = SR.GetResourceString("Globalization_cp_" + codePage.ToString());
             if (string.IsNullOrEmpty(displayName))
-                displayName = s_englishNames[s_englishNameIndices[englishNameIndex]..s_englishNameIndices[englishNameIndex + 1]];
+                displayName = EnglishNames[EnglishNameIndices[englishNameIndex]..EnglishNameIndices[englishNameIndex + 1]];
 
             return displayName;
         }
index e4c4e3457008ff244cef55ef4b324156fd207c2a..b618734d401e6ad74bd2bc8aa40572560c4332d6 100644 (file)
@@ -13,19 +13,6 @@ namespace System.Text
 {
     public class UTF7Encoding : Encoding
     {
-        private const string base64Chars =
-            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-        // 0123456789111111111122222222223333333333444444444455555555556666
-        //              012345678901234567890123456789012345678901234567890123
-
-        // These are the characters that can be directly encoded in UTF7.
-        private const string directChars =
-            "\t\n\r '(),-./0123456789:?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-        // These are the characters that can be optionally directly encoded in UTF7.
-        private const string optionalChars =
-            "!\"#$%&*;<=>@[]^_`{|}";
-
 #pragma warning disable SYSLIB0001
         // Used by Encoding.UTF7 for lazy initialization
         // The initialization code will not be run until a static member of the class is referenced
@@ -70,24 +57,30 @@ namespace System.Text
         private void MakeTables()
         {
             // Build our tables
-            _base64Bytes = new byte[64];
-            for (int i = 0; i < 64; i++) _base64Bytes[i] = (byte)base64Chars[i];
+
+            _base64Bytes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"u8.ToArray();
+            Debug.Assert(_base64Bytes.Length == 64);
+
             _base64Values = new sbyte[128];
             for (int i = 0; i < 128; i++) _base64Values[i] = -1;
             for (int i = 0; i < 64; i++) _base64Values[_base64Bytes[i]] = (sbyte)i;
+
+            // These are the characters that can be directly encoded in UTF7.
+            ReadOnlySpan<byte> directChars = "\t\n\r '(),-./0123456789:?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"u8;
             _directEncode = new bool[128];
-            int count = directChars.Length;
-            for (int i = 0; i < count; i++)
+            foreach (byte c in directChars)
             {
-                _directEncode[directChars[i]] = true;
+                _directEncode[c] = true;
             }
 
             if (_allowOptionals)
             {
-                count = optionalChars.Length;
-                for (int i = 0; i < count; i++)
+                // These are the characters that can be optionally directly encoded in UTF7.
+                ReadOnlySpan<byte> optionalChars = "!\"#$%&*;<=>@[]^_`{|}"u8;
+
+                foreach (byte c in optionalChars)
                 {
-                    _directEncode[optionalChars[i]] = true;
+                    _directEncode[c] = true;
                 }
             }
         }
index daeb79990449a1e4160f0a176cd3b4d4feb67cf2..84c261c0cdb54aaf5f20176465600c136e05cba8 100644 (file)
@@ -912,7 +912,7 @@ namespace System
                 index++;
             } while ((uint)index < (uint)date.Length && char.IsAsciiDigit(date[index]));
 
-            int[] days = GregorianCalendarHelper.DaysToMonth365;
+            ReadOnlySpan<int> days = GregorianCalendar.DaysToMonth365;
 
             if (julianDay == 0 || julianDay > days[days.Length - 1])
             {
index b1cb4458d86b99076786c7a0efb7b46f90fbadd8..9bc1ae31a159a795f0e90e78a7574cf962334a70 100644 (file)
@@ -161,24 +161,26 @@ namespace System.Runtime.Serialization
 
         private static int GetPrime(int min)
         {
-            for (int i = 0; i < primes.Length; i++)
+            ReadOnlySpan<int> primes = new int[]
             {
-                int prime = primes[i];
-                if (prime >= min) return prime;
+                3, 7, 17, 37, 89, 197, 431, 919, 1931, 4049, 8419, 17519, 36353,
+                75431, 156437, 324449, 672827, 1395263, 2893249, 5999471,
+                11998949, 23997907, 47995853, 95991737, 191983481, 383966977, 767933981, 1535867969,
+                2146435069, 0x7FFFFFC7
+                // 0x7FFFFFC7 == Array.MaxLength is not prime, but it is the largest possible array size.
+                // There's nowhere to go from here. Using a const rather than the MaxLength property
+                // so that the array contains only const values.
+            };
+
+            foreach (int prime in primes)
+            {
+                if (prime >= min)
+                {
+                    return prime;
+                }
             }
 
             return min;
         }
-
-        internal static readonly int[] primes =
-        {
-            3, 7, 17, 37, 89, 197, 431, 919, 1931, 4049, 8419, 17519, 36353,
-            75431, 156437, 324449, 672827, 1395263, 2893249, 5999471,
-            11998949, 23997907, 47995853, 95991737, 191983481, 383966977, 767933981, 1535867969,
-            2146435069, 0x7FFFFFC7
-            // 0x7FFFFFC7 == Array.MaxLength is not prime, but it is the largest possible array size.
-            // There's nowhere to go from here. Using a const rather than the MaxLength property
-            // so that the array contains only const values.
-        };
     }
 }
index 4bc3d0702bd8591edd787c9ab6020b2f48b7fd26..dbda45dc02d7a913f58dd16289825cd1bd684205 100644 (file)
@@ -13,7 +13,7 @@ namespace System.Xml
         private const int guidLength = 16;
         private const int uuidLength = 45;
 
-        private static readonly short[] s_char2val = new short[256]
+        private static ReadOnlySpan<short> Char2val => new short[256]
         {
             /*    0-15 */
                               0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100,
@@ -162,7 +162,7 @@ namespace System.Xml
 
             int i = 0;
             int j = 0;
-            fixed (short* ps = &s_char2val[0])
+            fixed (short* ps = &Char2val[0])
             {
                 short* _char2val = ps;
 
index de86a3abaf022dea8b6a460950b3048dea39713e..8bf77baf64a4272ebc6312fd8ca43ba73e2b666f 100644 (file)
@@ -16,7 +16,7 @@ namespace System.Xml.XPath
             (1 << (int)XmlNodeType.Element) |
             (1 << (int)XmlNodeType.ProcessingInstruction) |
             (1 << (int)XmlNodeType.Comment);
-        private static readonly int[] s_ElementContentMasks = {
+        private static ReadOnlySpan<int> ElementContentMasks => new int[] {
             0,                                              // Root
             (1 << (int)XmlNodeType.Element),                // Element
             0,                                              // Attribute
@@ -765,7 +765,7 @@ namespace System.Xml.XPath
 
         private static int GetElementContentMask(XPathNodeType type)
         {
-            return s_ElementContentMasks[(int)type];
+            return ElementContentMasks[(int)type];
         }
 
         private static XAttribute? GetFirstNamespaceDeclarationGlobal(XElement e)
index bb8dbbd5f63a59d778a5c64a06e1655b5f9e70a9..3c421935931a40859c010decfe5f4a0a392f7dfe 100644 (file)
@@ -18,7 +18,6 @@ namespace System.Xml
         private int _bits;
         private int _bitsFilled;
 
-        private const string CharsBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
         private static readonly byte[] s_mapBase64 = ConstructMapBase64();
         private const int MaxValidChar = (int)'z';
         private const byte Invalid = unchecked((byte)-1);
@@ -106,14 +105,14 @@ namespace System.Xml
         private static byte[] ConstructMapBase64()
         {
             byte[] mapBase64 = new byte[MaxValidChar + 1];
-            for (int i = 0; i < mapBase64.Length; i++)
-            {
-                mapBase64[i] = Invalid;
-            }
-            for (int i = 0; i < CharsBase64.Length; i++)
+            Array.Fill(mapBase64, Invalid);
+
+            ReadOnlySpan<byte> charsBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"u8;
+            for (int i = 0; i < charsBase64.Length; i++)
             {
-                mapBase64[(int)CharsBase64[i]] = (byte)i;
+                mapBase64[charsBase64[i]] = (byte)i;
             }
+
             return mapBase64;
         }
 
index 7d148ecfabcc888ca7b4927a3899f5b59b9ec142..f237a4608c779959134ddcb2742a044eddd9b9de 100644 (file)
@@ -598,7 +598,7 @@ namespace System.Xml.Schema
         //
         // for 'block' and 'final' attribute values
         //
-        private static readonly int[] s_derivationMethodValues = {
+        private static ReadOnlySpan<int> DerivationMethodValues => new int[] {
             (int)XmlSchemaDerivationMethod.Substitution,
             (int)XmlSchemaDerivationMethod.Extension,
             (int)XmlSchemaDerivationMethod.Restriction,
@@ -2525,12 +2525,12 @@ namespace System.Xml.Schema
                 {
                     if (stringValues[i] == s_derivationMethodStrings[j])
                     {
-                        if ((r & s_derivationMethodValues[j]) != 0 && (r & s_derivationMethodValues[j]) != s_derivationMethodValues[j])
+                        if ((r & DerivationMethodValues[j]) != 0 && (r & DerivationMethodValues[j]) != DerivationMethodValues[j])
                         {
                             SendValidationEvent(SR.Sch_InvalidXsdAttributeValue, attributeName, value, null);
                             return 0;
                         }
-                        r |= s_derivationMethodValues[j];
+                        r |= DerivationMethodValues[j];
                         matched = true;
                         break;
                     }
index c8110320f5189838b1aafeb52a9f36d7deec8b98..f82937036093f05e74709b8f9bae64107232097c 100644 (file)
@@ -82,8 +82,8 @@ namespace System.Xml.Schema
         private const int ZoneHourShift = 8;
 
         // Maximum number of fraction digits;
-        private const short maxFractionDigits = 7;
-        private const int ticksToFractionDivisor = 10000000;
+        private const short MaxFractionDigits = 7;
+        private const int TicksToFractionDivisor = 10000000;
 
         private static readonly int s_lzyyyy = "yyyy".Length;
         private static readonly int s_lzyyyy_ = "yyyy-".Length;
@@ -127,9 +127,9 @@ namespace System.Xml.Schema
         // Number of days in 400 years
         private const int DaysPer400Years = DaysPer100Years * 4 + 1; // 146097
 
-        private static readonly int[] DaysToMonth365 = {
+        private static ReadOnlySpan<int> DaysToMonth365 => new int[] {
             0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
-        private static readonly int[] DaysToMonth366 = {
+        private static ReadOnlySpan<int> DaysToMonth366 => new int[] {
             0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
 
         /// <summary>
@@ -329,7 +329,7 @@ namespace System.Xml.Schema
         /// </summary>
         public int Fraction
         {
-            get { return (int)(_dt.Ticks % ticksToFractionDivisor); }
+            get { return (int)(_dt.Ticks % TicksToFractionDivisor); }
         }
 
         /// <summary>
@@ -592,7 +592,7 @@ namespace System.Xml.Schema
             // Leap year calculation looks different from IsLeapYear since y1, y4,
             // and y100 are relative to year 1, not year 0
             bool leapYear = y1 == 3 && (y4 != 24 || y100 == 3);
-            int[] days = leapYear ? DaysToMonth366 : DaysToMonth365;
+            ReadOnlySpan<int> days = leapYear ? DaysToMonth366 : DaysToMonth365;
             // All months have less than 32 days, so n >> 5 is a good conservative
             // estimate for the month
             month = (n >> 5) + 1;
@@ -615,7 +615,7 @@ namespace System.Xml.Schema
             int fraction = Fraction;
             if (fraction != 0)
             {
-                int fractionDigits = maxFractionDigits;
+                int fractionDigits = MaxFractionDigits;
                 while (fraction % 10 == 0)
                 {
                     fractionDigits--;
@@ -910,7 +910,7 @@ namespace System.Xml.Schema
                 return false;
             }
 
-            private static readonly int[] s_power10 = new int[maxFractionDigits] { -1, 10, 100, 1000, 10000, 100000, 1000000 };
+            private static ReadOnlySpan<int> Power10 => new int[MaxFractionDigits] { -1, 10, 100, 1000, 10000, 100000, 1000000 };
             private bool ParseTime(ref int start)
             {
                 if (
@@ -936,11 +936,11 @@ namespace System.Xml.Schema
                             { // d < 0 || 9 < d
                                 break;
                             }
-                            if (fractionDigits < maxFractionDigits)
+                            if (fractionDigits < MaxFractionDigits)
                             {
                                 this.fraction = (this.fraction * 10) + d;
                             }
-                            else if (fractionDigits == maxFractionDigits)
+                            else if (fractionDigits == MaxFractionDigits)
                             {
                                 if (5 < d)
                                 {
@@ -957,13 +957,13 @@ namespace System.Xml.Schema
                             }
                             fractionDigits++;
                         }
-                        if (fractionDigits < maxFractionDigits)
+                        if (fractionDigits < MaxFractionDigits)
                         {
                             if (fractionDigits == 0)
                             {
                                 return false; // cannot end with .
                             }
-                            fraction *= s_power10[maxFractionDigits - fractionDigits];
+                            fraction *= Power10[MaxFractionDigits - fractionDigits];
                         }
                         else
                         {
index d749d8ec9feac2067c97252f074802c287a0d58b..8079d606ffe69a6dbf7e96e76ee72f528a5b879b 100644 (file)
@@ -99,9 +99,6 @@ namespace System.Xml.Xsl.Runtime
         private const string RomanDigitsUC = "IIVIXXLXCCDCM";
         private const string RomanDigitsLC = "iivixxlxccdcm";
 
-        //                            RomanDigit       = { I  IV   V  IX   X  XL   L  XC    C   CD    D   CM     M }
-        private static readonly int[] s_romanDigitValue = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
-
         public static void ConvertToRoman(StringBuilder sb, double val, bool upperCase)
         {
             Debug.Assert(1 <= val && val <= MaxRomanValue);
@@ -109,11 +106,14 @@ namespace System.Xml.Xsl.Runtime
             int number = (int)val;
             string digits = upperCase ? RomanDigitsUC : RomanDigitsLC;
 
-            for (int idx = s_romanDigitValue.Length; idx-- != 0;)
+            //                         RomanDigit       = { I IV  V IX   X  XL   L  XC    C   CD    D   CM     M }
+            ReadOnlySpan<int> RomanDigitValue = new int[] { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
+
+            for (int idx = RomanDigitValue.Length; idx-- != 0;)
             {
-                while (number >= s_romanDigitValue[idx])
+                while (number >= RomanDigitValue[idx])
                 {
-                    number -= s_romanDigitValue[idx];
+                    number -= RomanDigitValue[idx];
                     sb.Append(digits, idx, 1 + (idx & 1));
                 }
             }
index 2e111fd63e84a78fc500477ce3c04b3ad58862d5..14496cdc081885aa48e97e2e0e1716c24f74e322 100644 (file)
@@ -89,7 +89,7 @@ namespace System.Xml.Xsl
 
         // Small powers of ten. These are all the powers of ten that have an exact
         // representation in IEEE double precision format.
-        public static readonly double[] C10toN = {
+        public static ReadOnlySpan<double> C10toN => new double[] {
             1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09,
             1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
             1e20, 1e21, 1e22,
index 83fad3f14b8894cccb62168e1ae2c938251216dd..16aa8dafdd69a39abe844e66008bc94e88ac7281 100644 (file)
@@ -287,7 +287,8 @@ namespace System.Numerics
                                                            | NumberStyles.AllowThousands | NumberStyles.AllowExponent
                                                            | NumberStyles.AllowCurrencySymbol | NumberStyles.AllowHexSpecifier);
 
-        private static readonly uint[] s_uint32PowersOfTen = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
+        private static ReadOnlySpan<uint> UInt32PowersOfTen => new uint[] { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
+
         internal enum ParsingStatus
         {
             OK,
@@ -579,7 +580,7 @@ namespace System.Numerics
 
                 if (partialDigitCount > 0)
                 {
-                    MultiplyAdd(ref currentBuffer, s_uint32PowersOfTen[partialDigitCount], partialValue);
+                    MultiplyAdd(ref currentBuffer, UInt32PowersOfTen[partialDigitCount], partialValue);
                 }
 
                 result = NumberBufferToBigInteger(currentBuffer, number.sign);
@@ -817,7 +818,7 @@ namespace System.Numerics
 
                 if (trailingZeroCount > 0)
                 {
-                    MultiplyAdd(ref currentBuffer, s_uint32PowersOfTen[trailingZeroCount], 0);
+                    MultiplyAdd(ref currentBuffer, UInt32PowersOfTen[trailingZeroCount], 0);
                 }
 
                 int sign;
index cfa39e599f7d53f491f94b861e30d826c866d2b4..ca61f24b0f7f6f16a36445824fe326a049813d2c 100644 (file)
@@ -244,7 +244,7 @@ namespace System.Security.Cryptography
                 return hash;
             }
 
-            private static readonly uint[] _K = {
+            private static ReadOnlySpan<uint> _K => new uint[] {
                 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
                 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
                 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
@@ -522,7 +522,7 @@ namespace System.Security.Cryptography
                 return hash;
             }
 
-            private static readonly ulong[] _K = {
+            private static ReadOnlySpan<ulong> _K => new ulong[] {
                 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
                 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
                 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
@@ -810,7 +810,7 @@ namespace System.Security.Cryptography
                 return hash;
             }
 
-            private static readonly ulong[] _K = {
+            private static ReadOnlySpan<ulong> _K => new ulong[] {
                 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
                 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
                 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
index 4bce132659d533c5ddbfff62ce09c3da019e7400..b920563ecda986a245adcc2534b49d3a08d4189d 100644 (file)
@@ -319,13 +319,13 @@ namespace {2}
         // Ordered by alphabetized IANA name
         private const string EncodingNames =
 @"
-        // s_encodingNames is the concatenation of all supported IANA names for each codepage.
+        // EncodingNames is the concatenation of all supported IANA names for each codepage.
         // This is done rather than using a large readonly array of strings to avoid
         // generating a large amount of code in the static constructor.
-        // Using indices from s_encodingNamesIndices, we binary search this string when mapping
+        // Using indices from EncodingNamesIndices, we binary search this string when mapping
         // an encoding name to a codepage. Note that these names are all lowercase and are
         // sorted alphabetically.
-        private const string s_encodingNames =|
+        private const string EncodingNames =|
             ""{0}"" + // {1:D}|
             """";
 ";
@@ -338,10 +338,10 @@ namespace {2}
         // Ordered by alphabetized IANA name
         private const string EncodingNameIndices =
 @"
-        // s_encodingNameIndices contains the start index of every encoding name in the string
-        // s_encodingNames. We infer the length of each string by looking at the start index
+        // EncodingNameIndices contains the start index of every encoding name in the string
+        // EncodingNames. We infer the length of each string by looking at the start index
         // of the next string.
-        private static readonly int[] s_encodingNameIndices = new int[]
+        private static ReadOnlySpan<int> EncodingNameIndices => new int[]
         {
             0|, // {0} ({1:D})
             {2:D}|
@@ -354,11 +354,11 @@ namespace {2}
         // Ordered by alphabetized IANA name
         private const string CodePagesByName =
 @"
-        // s_codePagesByName contains the list of supported codepages which match the encoding
-        // names listed in s_encodingNames. The way mapping works is we binary search
-        // s_encodingNames using s_encodingNamesIndices until we find a match for a given name.
-        // The index of the entry in s_encodingNamesIndices will be the index of codepage in s_codePagesByName.
-        private static readonly ushort[] s_codePagesByName = new ushort[]
+        // CodePagesByName contains the list of supported codepages which match the encoding
+        // names listed in EncodingNames. The way mapping works is we binary search
+        // EncodingNames using EncodingNamesIndices until we find a match for a given name.
+        // The index of the entry in EncodingNamesIndices will be the index of codepage in CodePagesByName.
+        private static ReadOnlySpan<ushort> CodePagesByName => new ushort[]
         {|
             {0:D}, // {1}|
         };
@@ -375,8 +375,8 @@ namespace {2}
         // we perform a linear search on s_mappedCodePages to find the index of the
         // given codepage. This is used to index WebNameIndices to get the start
         // index of the web name in the string WebNames, and to index
-        // s_englishNameIndices to get the start of the English name in s_englishNames.
-        private static readonly ushort[] s_mappedCodePages = new ushort[]
+        // EnglishNameIndices to get the start of the English name in EnglishNames.
+        private static ReadOnlySpan<ushort> s_mappedCodePages => new ushort[]
         {|
             {0:D}, // {1}|
         };
@@ -388,12 +388,12 @@ namespace {2}
         // Ordered by codepage
         private const string WebNames =
 @"
-        // s_webNames is a concatenation of the default encoding names
+        // WebNames is a concatenation of the default encoding names
         // for each code page. It is used in retrieving the value for
         // System.Text.Encoding.WebName given System.Text.Encoding.CodePage.
         // This is done rather than using a large readonly array of strings to avoid
         // generating a large amount of code in the static constructor.
-        private const string s_webNames =|
+        private const string WebNames =|
             ""{0}"" + // {1:D}|
             """";
 ";
@@ -406,10 +406,10 @@ namespace {2}
         // Ordered by codepage
         private const string WebNameIndices =
 @"
-        // s_webNameIndices contains the start index of each code page's default
-        // web name in the string s_webNames. It is indexed by an index into
+        // WebNameIndices contains the start index of each code page's default
+        // web name in the string WebNames. It is indexed by an index into
         // s_mappedCodePages.
-        private static readonly int[] s_webNameIndices = new int[]
+        private static ReadOnlySpan<int> WebNameIndices => new int[]
         {
             0|, // {0} ({1:D})
             {2:D}|
@@ -422,12 +422,12 @@ namespace {2}
         // Ordered by codepage
         private const string EnglishNames =
 @"
-        // s_englishNames is the concatenation of the English names for each codepage.
+        // EnglishNames is the concatenation of the English names for each codepage.
         // It is used in retrieving the value for System.Text.Encoding.EncodingName
         // given System.Text.Encoding.CodePage.
         // This is done rather than using a large readonly array of strings to avoid
         // generating a large amount of code in the static constructor.
-        private const string s_englishNames =|
+        private const string EnglishNames =|
             ""{0}"" + // {1:D}|
             """";
 ";
@@ -440,9 +440,9 @@ namespace {2}
         // Ordered by codepage
         private const string EnglishNameIndices =
 @"
-        // s_englishNameIndices contains the start index of each code page's English
-        // name in the string s_englishNames. It is indexed by an index into s_mappedCodePages.
-        private static readonly int[] s_englishNameIndices = new int[]
+        // EnglishNameIndices contains the start index of each code page's English
+        // name in the string EnglishNames. It is indexed by an index into s_mappedCodePages.
+        private static ReadOnlySpan<int> EnglishNameIndices => new int[]
         {
             0|, // {0} ({1:D})
             {2:D}|
index 9382494e564aa782bcbbaf490abe9e6214ed7e9f..72ff6d8f7cbbbdfa804439b5450374c1b79bb4b6 100644 (file)
@@ -18,7 +18,7 @@ namespace System.Text
         // Using indices from s_encodingNamesIndices, we binary search this string when mapping
         // an encoding name to a codepage. Note that these names are all lowercase and are
         // sorted alphabetically.
-        private const string s_encodingNames =
+        private const string EncodingNames =
             "437" + // 437
             "arabic" + // 28596
             "asmo-708" + // 708
@@ -388,7 +388,7 @@ namespace System.Text
         // s_encodingNameIndices contains the start index of every encoding name in the string
         // s_encodingNames. We infer the length of each string by looking at the start index
         // of the next string.
-        private static readonly int[] s_encodingNameIndices = new int[]
+        private static ReadOnlySpan<int> EncodingNameIndices => new int[]
         {
             0, // 437 (437)
             3, // arabic (28596)
@@ -761,7 +761,7 @@ namespace System.Text
         // names listed in s_encodingNames. The way mapping works is we binary search
         // s_encodingNames using s_encodingNamesIndices until we find a match for a given name.
         // The index of the entry in s_encodingNamesIndices will be the index of codepage in s_codePagesByName.
-        private static readonly ushort[] s_codePagesByName = new ushort[]
+        private static ReadOnlySpan<ushort> CodePagesByName => new ushort[]
         {
             437, // 437
             28596, // arabic
@@ -1135,7 +1135,7 @@ namespace System.Text
         // given codepage. This is used to index WebNameIndices to get the start
         // index of the web name in the string WebNames, and to index
         // s_englishNameIndices to get the start of the English name in s_englishNames.
-        private static readonly ushort[] s_mappedCodePages = new ushort[]
+        private static ReadOnlySpan<ushort> MappedCodePages => new ushort[]
         {
             37, // ibm037
             437, // ibm437
@@ -1276,7 +1276,7 @@ namespace System.Text
         // System.Text.Encoding.WebName given System.Text.Encoding.CodePage.
         // This is done rather than using a large readonly array of strings to avoid
         // generating a large amount of code in the static constructor.
-        private const string s_webNames =
+        private const string WebNames =
             "ibm037" + // 37
             "ibm437" + // 437
             "ibm500" + // 500
@@ -1414,7 +1414,7 @@ namespace System.Text
         // s_webNameIndices contains the start index of each code page's default
         // web name in the string s_webNames. It is indexed by an index into
         // s_mappedCodePages.
-        private static readonly int[] s_webNameIndices = new int[]
+        private static ReadOnlySpan<int> WebNameIndices => new int[]
         {
             0, // ibm037 (37)
             6, // ibm437 (437)
@@ -1556,7 +1556,7 @@ namespace System.Text
         // given System.Text.Encoding.CodePage.
         // This is done rather than using a large readonly array of strings to avoid
         // generating a large amount of code in the static constructor.
-        private const string s_englishNames =
+        private const string EnglishNames =
             "IBM EBCDIC (US-Canada)" + // 37
             "OEM United States" + // 437
             "IBM EBCDIC (International)" + // 500
@@ -1693,7 +1693,7 @@ namespace System.Text
 
         // s_englishNameIndices contains the start index of each code page's English
         // name in the string s_englishNames. It is indexed by an index into s_mappedCodePages.
-        private static readonly int[] s_englishNameIndices = new int[]
+        private static ReadOnlySpan<int> EnglishNameIndices => new int[]
         {
             0, // IBM EBCDIC (US-Canada) (37)
             22, // OEM United States (437)
index c0ad4ece91f89dcfecbbc4002ff512bead46355c..f177657428cf6bce30e60e192a2568abf76f54c4 100644 (file)
@@ -1,7 +1,6 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Threading;
@@ -62,13 +61,15 @@ namespace System.Text
 
         private static int InternalGetCodePageFromName(string name)
         {
+            ReadOnlySpan<int> encodingNameIndices = EncodingNameIndices;
+
             int left = 0;
-            int right = s_encodingNameIndices.Length - 2;
+            int right = encodingNameIndices.Length - 2;
             int index;
             int result;
 
-            Debug.Assert(s_encodingNameIndices.Length == s_codePagesByName.Length + 1);
-            Debug.Assert(s_encodingNameIndices[s_encodingNameIndices.Length - 1] == s_encodingNames.Length);
+            Debug.Assert(encodingNameIndices.Length == CodePagesByName.Length + 1);
+            Debug.Assert(encodingNameIndices[encodingNameIndices.Length - 1] == EncodingNames.Length);
 
             name = name.ToLowerInvariant();
 
@@ -78,12 +79,12 @@ namespace System.Text
             {
                 index = ((right - left) / 2) + left;
 
-                Debug.Assert(index < s_encodingNameIndices.Length - 1);
-                result = CompareOrdinal(name, s_encodingNames, s_encodingNameIndices[index], s_encodingNameIndices[index + 1] - s_encodingNameIndices[index]);
+                Debug.Assert(index < encodingNameIndices.Length - 1);
+                result = CompareOrdinal(name, EncodingNames, encodingNameIndices[index], encodingNameIndices[index + 1] - encodingNameIndices[index]);
                 if (result == 0)
                 {
                     //We found the item, return the associated codePage.
-                    return (s_codePagesByName[index]);
+                    return CodePagesByName[index];
                 }
                 else if (result < 0)
                 {
@@ -100,10 +101,10 @@ namespace System.Text
             //Walk the remaining elements (it'll be 3 or fewer).
             for (; left <= right; left++)
             {
-                Debug.Assert(left < s_encodingNameIndices.Length - 1);
-                if (CompareOrdinal(name, s_encodingNames, s_encodingNameIndices[left], s_encodingNameIndices[left + 1] - s_encodingNameIndices[left]) == 0)
+                Debug.Assert(left < encodingNameIndices.Length - 1);
+                if (CompareOrdinal(name, EncodingNames, encodingNameIndices[left], encodingNameIndices[left + 1] - encodingNameIndices[left]) == 0)
                 {
-                    return (s_codePagesByName[left]);
+                    return CodePagesByName[left];
                 }
             }
 
@@ -129,19 +130,19 @@ namespace System.Text
 
         internal static string? GetWebNameFromCodePage(int codePage)
         {
-            return GetNameFromCodePage(codePage, s_webNames, s_webNameIndices, s_codePageToWebNameCache);
+            return GetNameFromCodePage(codePage, WebNames, WebNameIndices, s_codePageToWebNameCache);
         }
 
         internal static string? GetEnglishNameFromCodePage(int codePage)
         {
-            return GetNameFromCodePage(codePage, s_englishNames, s_englishNameIndices, s_codePageToEnglishNameCache);
+            return GetNameFromCodePage(codePage, EnglishNames, EnglishNameIndices, s_codePageToEnglishNameCache);
         }
 
-        private static string? GetNameFromCodePage(int codePage, string names, int[] indices, Dictionary<int, string> cache)
+        private static string? GetNameFromCodePage(int codePage, string names, ReadOnlySpan<int> indices, Dictionary<int, string> cache)
         {
             string? name;
 
-            Debug.Assert(s_mappedCodePages.Length + 1 == indices.Length);
+            Debug.Assert(MappedCodePages.Length + 1 == indices.Length);
             Debug.Assert(indices[indices.Length - 1] == names.Length);
 
             if ((uint)codePage > ushort.MaxValue)
@@ -150,7 +151,7 @@ namespace System.Text
             }
 
             //This is a linear search, but we probably won't be doing it very often.
-            int i = Array.IndexOf(s_mappedCodePages, (ushort)codePage);
+            int i = MappedCodePages.IndexOf((ushort)codePage);
             if (i < 0)
             {
                 // Didn't find it.
index 4c277685b6d7e10786d70aa0645cadaaadc013a9..09a69634bfa880c531c93dec6ad96f9f4019c79e 100644 (file)
@@ -538,7 +538,7 @@ namespace System.Text.Json
 
             Debug.Assert(parseData.Fraction >= 0 && parseData.Fraction <= JsonConstants.MaxDateTimeFraction); // All of our callers to date parse the fraction from fixed 7-digit fields so this value is trusted.
 
-            int[] days = DateTime.IsLeapYear(parseData.Year) ? s_daysToMonth366 : s_daysToMonth365;
+            ReadOnlySpan<int> days = DateTime.IsLeapYear(parseData.Year) ? DaysToMonth366 : DaysToMonth365;
             int yearMinusOne = parseData.Year - 1;
             int totalDays = (yearMinusOne * 365) + (yearMinusOne / 4) - (yearMinusOne / 100) + (yearMinusOne / 400) + days[parseData.Month - 1] + parseData.Day - 1;
             long ticks = totalDays * TimeSpan.TicksPerDay;
@@ -549,7 +549,7 @@ namespace System.Text.Json
             return true;
         }
 
-        private static readonly int[] s_daysToMonth365 = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
-        private static readonly int[] s_daysToMonth366 = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
+        private static ReadOnlySpan<int> DaysToMonth365 => new int[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+        private static ReadOnlySpan<int> DaysToMonth366 => new int[] { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
     }
 }
index 888d23f524a52650cb87ce826f2fdc584761c690..393968ad57e3248762aed8f93be00c97cb4bffd6 100644 (file)
@@ -9,7 +9,7 @@ namespace System.Text.RegularExpressions
         // PLEASE DON'T MODIFY BY HAND
         // IF YOU NEED TO UPDATE UNICODE VERSION FOLLOW THE GUIDE AT src/libraries/System.Private.CoreLib/Tools/GenUnicodeProp/Updating-Unicode-Versions.md
 
-        private static char[] EquivalenceCasingValues { get; } = new char[2336]
+        private static ReadOnlySpan<char> EquivalenceCasingValues => new char[2336]
         {
             '\u0041', '\u0061', '\u0042', '\u0062', '\u0043', '\u0063', '\u0044', '\u0064', '\u0045', '\u0065', '\u0046', '\u0066', '\u0047', '\u0067', '\u0048', '\u0068',
             '\u0049', '\u0069', '\u004A', '\u006A', '\u004B', '\u006B', '\u212A', '\u004C', '\u006C', '\u004D', '\u006D', '\u004E', '\u006E', '\u004F', '\u006F', '\u0050',
@@ -159,7 +159,7 @@ namespace System.Text.RegularExpressions
             '\uFF33', '\uFF53', '\uFF34', '\uFF54', '\uFF35', '\uFF55', '\uFF36', '\uFF56', '\uFF37', '\uFF57', '\uFF38', '\uFF58', '\uFF39', '\uFF59', '\uFF3A', '\uFF5A'
         };
 
-        private static ushort[] EquivalenceFirstLevelLookup { get; } = new ushort[64]
+        private static ReadOnlySpan<ushort> EquivalenceFirstLevelLookup => new ushort[64]
         {
             0x0000, 0x0400, 0xffff, 0xffff, 0x0800, 0xffff, 0xffff, 0x0c00, 0x1000, 0x1400, 0xffff, 0x1800, 0xffff, 0xffff, 0xffff, 0xffff,
             0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
@@ -167,7 +167,7 @@ namespace System.Text.RegularExpressions
             0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x2400
         };
 
-        private static ushort[] EquivalenceCasingMap { get; } = new ushort[10240]
+        private static ReadOnlySpan<ushort> EquivalenceCasingMap => new ushort[10240]
         {
             0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
             0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
index 72a61998b8ccf0941497ab5123f8bb2d1faafc56..4367da61026dca28d341839ee89c6b41f8d0c3be 100644 (file)
@@ -16,11 +16,6 @@ namespace System.Text.RegularExpressions
     {
         public const int CharactersPerRange = 1024;
 
-        private static readonly char[] s_specialCasingSetBehaviors = new char[5]
-        {
-            'I', 'i', '\u0130', 'I', '\u0131'
-        };
-
         /// <summary>
         /// Performs a fast lookup which determines if a character is involved in case conversion, as well as
         /// returns the characters that should be considered equivalent in case it does participate in case conversion.
@@ -45,14 +40,14 @@ namespace System.Text.RegularExpressions
                 equivalences = c switch
                 {
                     // Invariant mappings
-                    'i' or 'I' when mappingBehavior is RegexCaseBehavior.Invariant => s_specialCasingSetBehaviors.AsSpan(0, 2), // 'I' and 'i'
+                    'i' or 'I' when mappingBehavior is RegexCaseBehavior.Invariant => "Ii".AsSpan(),
 
                     // Non-Turkish mappings
-                    'i' or 'I' or '\u0130' when mappingBehavior is RegexCaseBehavior.NonTurkish => s_specialCasingSetBehaviors.AsSpan(0, 3), // 'I', 'i', and '\u0130'
+                    'i' or 'I' or '\u0130' when mappingBehavior is RegexCaseBehavior.NonTurkish => "Ii\u0130".AsSpan(),
 
                     // Turkish mappings
-                    'I' or '\u0131' when mappingBehavior is RegexCaseBehavior.Turkish => s_specialCasingSetBehaviors.AsSpan(3, 2), // 'I' and '\u0131'
-                    'i' or '\u0130' when mappingBehavior is RegexCaseBehavior.Turkish => s_specialCasingSetBehaviors.AsSpan(1, 2), // 'i' and '\u0130'
+                    'I' or '\u0131' when mappingBehavior is RegexCaseBehavior.Turkish => "I\u0131".AsSpan(),
+                    'i' or '\u0130' when mappingBehavior is RegexCaseBehavior.Turkish => "i\u0130".AsSpan(),
 
                     // Default
                     _ => default
@@ -158,7 +153,7 @@ namespace System.Text.RegularExpressions
 
             byte count = (byte)((mappingValue >> 13) & 0b111);
             ushort index3 = (ushort)(mappingValue & 0x1FFF);
-            equivalences = EquivalenceCasingValues.AsSpan(index3, count);
+            equivalences = EquivalenceCasingValues.Slice(index3, count);
 
             return true;
         }
index 7185e4a62e7e6c2b9fb9c86c106670159dd0a61f..18a120bbede3a3b0bf6b0c2efa0dba8e155d4018 100644 (file)
@@ -110,8 +110,10 @@ namespace GenerateRegexCasingTable
 
             void EmitFirstLevelLookupTable(StreamWriter writer)
             {
-                var firstLevelLookupTable = FlattenFirstLevelLookupTable();
-                writer.Write("        private static ushort[] EquivalenceFirstLevelLookup { get; } = new ushort[" + firstLevelLookupTable.Count + "]\n        {\n");
+                List<ushort> firstLevelLookupTable = FlattenFirstLevelLookupTable();
+
+                writer.Write($"        private static ReadOnlySpan<ushort> EquivalenceFirstLevelLookup => new ushort[{firstLevelLookupTable.Count}]");
+                writer.Write("        {");
 
                 writer.Write("            0x{0:x4}", firstLevelLookupTable[0]);
                 for (var i = 1; i < firstLevelLookupTable.Count; i++)
@@ -146,8 +148,10 @@ namespace GenerateRegexCasingTable
 
             void EmitMapArray(StreamWriter writer)
             {
-                var flattenedMap = FlattenMapDictionary();
-                writer.Write("        private static ushort[] EquivalenceCasingMap { get; } = new ushort[" + flattenedMap.Count + "]\n        {\n");
+                List<ushort> flattenedMap = FlattenMapDictionary();
+
+                writer.Write($"        private static ReadOnlySpan<ushort> EquivalenceCasingMap => new ushort[{flattenedMap.Count}]");
+                writer.Write("        {");
 
                 writer.Write("            0x{0:x4}", flattenedMap[0]);
                 for (var i = 1; i < flattenedMap.Count; i++)
@@ -189,8 +193,12 @@ namespace GenerateRegexCasingTable
 
             void EmitValuesArray(StreamWriter writer)
             {
-                var flattenedValues = FlattenValuesDictionary();
-                writer.Write("        private static char[] EquivalenceCasingValues { get; } = new char[" + flattenedValues.Count + "]\n        {\n");
+                List<ushort> flattenedValues = FlattenValuesDictionary();
+
+                writer.Write($"        private static ReadOnlySpan<char> EquivalenceCasingValues => new char[{flattenedValues.Count}]");
+                writer.Write("        {");
+
+                writer.Write("        private static ReadOnlySpan<char> EquivalenceCasingValues => new char[" + flattenedValues.Count + "]\n        {\n");
 
                 writer.Write("            \'\\u{0:X4}\'", flattenedValues[0]);
                 for (var i = 1; i < flattenedValues.Count; i++)