{
// From ECMA CLI spec, Partition III, section 3.27:
//
- // If overflow occurs converting a floating-point type to an integer, or if the floating-point value
- // being converted to an integer is a NaN, the value returned is unspecified.
+ // If overflow occurs converting a floating-point type to an integer, or if the floating-point value
+ // being converted to an integer is a NaN, the value returned is unspecified.
//
// Based upon this, this method should be performing the comparison against the double
// before attempting a cast. Otherwise, the result is undefined.
/// Get the list of era values.
/// </summary>
/// <returns>The int array of the era names supported in this calendar or null if era is not used.</returns>
- public abstract int[]? Eras { get; }
+ public abstract int[] Eras { get; }
// Returns the hour part of the specified DateTime. The returned value is an
// integer between 0 and 23.
int day;
int dayOfYear = GetDayOfYear(time) - 1; // Make the day of year to be 0-based, so that 1/1 is day 0.
-
+
// Calculate the number of days between the first day of year (1/1) and the first day of the week.
// This value will be a positive value from 0 ~ 6. We call this value as "offset".
//
// Otherwise, the specified time falls on the week of previous year.
// Call this method again by passing the last day of previous year.
// the last day of the previous year may "underflow" to no longer be a valid date time for
- // this calendar if we just subtract so we need the subclass to provide us with
+ // this calendar if we just subtract so we need the subclass to provide us with
// that information
if (time <= MinSupportedDateTime.AddDays(dayOfYear))
{
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Collections.Generic;
using System.Diagnostics;
using System.Security;
private bool LoadCalendarDataFromSystem(string localeName, CalendarId calendarId)
{
bool result = true;
- result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.NativeName, out this.sNativeName);
- result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.MonthDay, out this.sMonthDay);
+ // TODO-NULLABLE: these can return null but are later replaced with String.Empty or other non-nullable value
+ result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.NativeName, out this.sNativeName!);
+ result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.MonthDay, out this.sMonthDay!);
this.sMonthDay = NormalizeDatePattern(this.sMonthDay);
- result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.ShortDates, out this.saShortDates);
- result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.LongDates, out this.saLongDates);
- result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.YearMonths, out this.saYearMonths);
- result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.DayNames, out this.saDayNames);
- result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.AbbrevDayNames, out this.saAbbrevDayNames);
- result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.SuperShortDayNames, out this.saSuperShortDayNames);
+ result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.ShortDates, out this.saShortDates!);
+ result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.LongDates, out this.saLongDates!);
+ result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.YearMonths, out this.saYearMonths!);
+ result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.DayNames, out this.saDayNames!);
+ result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.AbbrevDayNames, out this.saAbbrevDayNames!);
+ result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.SuperShortDayNames, out this.saSuperShortDayNames!);
- string leapHebrewMonthName = null;
- result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthNames, out this.saMonthNames, ref leapHebrewMonthName);
+ string? leapHebrewMonthName = null;
+ result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthNames, out this.saMonthNames!, ref leapHebrewMonthName);
if (leapHebrewMonthName != null)
- {
- // In Hebrew calendar, get the leap month name Adar II and override the non-leap month 7
+ {
+ Debug.Assert(this.saMonthNames != null);
+
+ // In Hebrew calendar, get the leap month name Adar II and override the non-leap month 7
Debug.Assert(calendarId == CalendarId.HEBREW && saMonthNames.Length == 13);
saLeapYearMonthNames = (string[]) saMonthNames.Clone();
saLeapYearMonthNames[6] = leapHebrewMonthName;
saMonthNames[6] = leapHebrewMonthName;
}
- result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthNames, out this.saAbbrevMonthNames, ref leapHebrewMonthName);
- result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthGenitiveNames, out this.saMonthGenitiveNames, ref leapHebrewMonthName);
- result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthGenitiveNames, out this.saAbbrevMonthGenitiveNames, ref leapHebrewMonthName);
+ result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthNames, out this.saAbbrevMonthNames!, ref leapHebrewMonthName);
+ result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthGenitiveNames, out this.saMonthGenitiveNames!, ref leapHebrewMonthName);
+ result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthGenitiveNames, out this.saAbbrevMonthGenitiveNames!, ref leapHebrewMonthName);
- result &= EnumEraNames(localeName, calendarId, CalendarDataType.EraNames, out this.saEraNames);
- result &= EnumEraNames(localeName, calendarId, CalendarDataType.AbbrevEraNames, out this.saAbbrevEraNames);
+ result &= EnumEraNames(localeName, calendarId, CalendarDataType.EraNames, out this.saEraNames!);
+ result &= EnumEraNames(localeName, calendarId, CalendarDataType.AbbrevEraNames, out this.saAbbrevEraNames!);
return result;
}
out calendarString);
}
- private static bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] datePatterns)
+ private static bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? datePatterns)
{
datePatterns = null;
{
if (s[index] == '\'')
{
- do
+ do
{
modifiedPattern[index] = s[index];
index++;
} while (index < s.Length && s[index] != '\'');
if (index >= s.Length)
- return;
+ return;
}
else if (s[index] == 'y')
{
return index - startIndex;
}
- private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] monthNames, ref string leapHebrewMonthName)
+ private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? monthNames, ref string? leapHebrewMonthName)
{
monthNames = null;
if (callbackContext.Results.Count > 13)
{
Debug.Assert(calendarId == CalendarId.HEBREW && callbackContext.Results.Count == 14);
-
+
if (calendarId == CalendarId.HEBREW)
{
leapHebrewMonthName = callbackContext.Results[13];
}
callbackContext.Results.RemoveRange(13, callbackContext.Results.Count - 13);
- }
+ }
monthNames = callbackContext.Results.ToArray();
}
return result;
}
- private static bool EnumEraNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] eraNames)
+ private static bool EnumEraNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? eraNames)
{
bool result = EnumCalendarInfo(localeName, calendarId, dataType, out eraNames);
// .NET expects that only the Japanese calendars have more than 1 era.
// So for other calendars, only return the latest era.
- if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames.Length > 0)
+ if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames?.Length > 0)
{
- string[] latestEraName = new string[] { eraNames[eraNames.Length - 1] };
+ string[] latestEraName = new string[] { eraNames![eraNames.Length - 1] };
eraNames = latestEraName;
}
return result;
}
- internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] calendarData)
+ internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? calendarData)
{
calendarData = null;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
namespace System.Globalization
//
// NOTE: Calendars depend on the locale name that creates it. Only a few
// properties are available without locales using CalendarData.GetCalendar(CalendarData)
-
+ //
+ // TODO-NULLABLE: this class requires refactoring for proper annotations
+ // currently from user of this class all fields are non-nullable.
+ // To avoid potential breaking changes lots of workaround have
+ // been used to suppress errors
internal partial class CalendarData
{
// Max calendars
internal const int MAX_CALENDARS = 23;
// Identity
- internal string sNativeName; // Calendar Name for the locale
+ internal string sNativeName = null!; // Calendar Name for the locale
// Formats
- internal string[] saShortDates; // Short Data format, default first
- internal string[] saYearMonths; // Year/Month Data format, default first
- internal string[] saLongDates; // Long Data format, default first
- internal string sMonthDay; // Month/Day format
+ internal string[] saShortDates = null!; // Short Data format, default first
+ internal string[] saYearMonths = null!; // Year/Month Data format, default first
+ internal string[] saLongDates = null!; // Long Data format, default first
+ internal string sMonthDay = null!; // Month/Day format
// Calendar Parts Names
- internal string[] saEraNames; // Names of Eras
- internal string[] saAbbrevEraNames; // Abbreviated Era Names
- internal string[] saAbbrevEnglishEraNames; // Abbreviated Era Names in English
- internal string[] saDayNames; // Day Names, null to use locale data, starts on Sunday
- internal string[] saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday
- internal string[] saSuperShortDayNames; // Super short Day of week names
- internal string[] saMonthNames; // Month Names (13)
- internal string[] saAbbrevMonthNames; // Abbrev Month Names (13)
- internal string[] saMonthGenitiveNames; // Genitive Month Names (13)
- internal string[] saAbbrevMonthGenitiveNames; // Genitive Abbrev Month Names (13)
- internal string[] saLeapYearMonthNames; // Multiple strings for the month names in a leap year.
+ internal string[] saEraNames = null!; // Names of Eras
+ internal string[] saAbbrevEraNames = null!; // Abbreviated Era Names
+ internal string[] saAbbrevEnglishEraNames = null!; // Abbreviated Era Names in English
+ internal string[] saDayNames = null!; // Day Names, null to use locale data, starts on Sunday
+ internal string[] saAbbrevDayNames = null!; // Abbrev Day Names, null to use locale data, starts on Sunday
+ internal string[] saSuperShortDayNames = null!; // Super short Day of week names
+ internal string[] saMonthNames = null!; // Month Names (13)
+ internal string[] saAbbrevMonthNames = null!; // Abbrev Month Names (13)
+ internal string[] saMonthGenitiveNames = null!; // Genitive Month Names (13)
+ internal string[] saAbbrevMonthGenitiveNames = null!; // Genitive Abbrev Month Names (13)
+ internal string[] saLeapYearMonthNames = null!; // Multiple strings for the month names in a leap year.
// Integers at end to make marshaller happier
internal int iTwoDigitYearMax = 2029; // Max 2 digit year (for Y2K bug data entry)
internal static readonly CalendarData Invariant = CreateInvariant();
// Private constructor
- private CalendarData() { }
+ private CalendarData()
+ {
+ }
// Invariant factory
private static CalendarData CreateInvariant()
this.saAbbrevEnglishEraNames = new string[] { "" };
}
- // Japanese is the only thing with > 1 era. Its current era # is how many ever
+ // Japanese is the only thing with > 1 era. Its current era # is how many ever
// eras are in the array. (And the others all have 1 string in the array)
this.iCurrentEra = this.saEraNames.Length;
}
{
// For Localized Gregorian we really expect the data from the OS.
case CalendarId.GREGORIAN:
- // Fallback for CoreCLR < Win7 or culture.dll missing
+ // Fallback for CoreCLR < Win7 or culture.dll missing
if (this.saEraNames == null || this.saEraNames.Length == 0 || string.IsNullOrEmpty(this.saEraNames[0]))
{
this.saEraNames = new string[] { "A.D." };
{
// For Localized Gregorian we really expect the data from the OS.
case CalendarId.GREGORIAN:
- // Fallback for CoreCLR < Win7 or culture.dll missing
+ // Fallback for CoreCLR < Win7 or culture.dll missing
if (this.saAbbrevEraNames == null || this.saAbbrevEraNames.Length == 0 || string.IsNullOrEmpty(this.saAbbrevEraNames[0]))
{
this.saAbbrevEraNames = new string[] { "AD" };
//
// Get a calendar.
// Unfortunately we depend on the locale in the OS, so we need a locale
- // no matter what. So just get the appropriate calendar from the
+ // no matter what. So just get the appropriate calendar from the
// appropriate locale here
//
}
}
}
-
}
}
- public override int[]? Eras => new int[] { ChineseEra };
+ public override int[] Eras => new int[] { ChineseEra };
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
using System.Runtime.InteropServices;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Buffers;
using System.Diagnostics;
using System.Runtime.CompilerServices;
public partial class CompareInfo
{
[NonSerialized]
- private Interop.Globalization.SafeSortHandle _sortHandle;
+ private Interop.Globalization.SafeSortHandle _sortHandle = null!;
[NonSerialized]
private bool _isAsciiEqualityOrdinal;
return -1;
}
- // startIndex is the index into source where we start search backwards from.
- // leftStartIndex is the index into source of the start of the string that is
+ // startIndex is the index into source where we start search backwards from.
+ // leftStartIndex is the index into source of the start of the string that is
// count characters away from startIndex.
int leftStartIndex = startIndex - count + 1;
// uppercase both chars - notice that we need just one compare per char
if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20;
if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20;
-
+
if (charA != charB)
return false;
{
int charA = *a;
int charB = *b;
-
+
if (charA != charB)
return false;
// uppercase both chars - notice that we need just one compare per char
if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20;
if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20;
-
+
if (charA != charB)
return false;
{
int charA = *a;
int charB = *b;
-
+
if (charA != charB)
return false;
{
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
-
+
byte [] keyData;
if (source.Length == 0)
- {
+ {
keyData = Array.Empty<Byte>();
}
else
}
return new SortKey(Name, source, options, keyData);
- }
+ }
private static unsafe bool IsSortable(char *text, int length)
{
{
int sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, null, 0, options);
- byte[] borrowedArr = null;
+ byte[]? borrowedArr = null;
Span<byte> span = sortKeyLength <= 512 ?
stackalloc byte[512] :
(borrowedArr = ArrayPool<byte>.Shared.Rent(sortKeyLength));
return buffer;
}
-
+
private SortVersion GetSortVersion()
{
Debug.Assert(!GlobalizationMode.Invariant);
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Buffers;
using System.Diagnostics;
using System.Runtime.InteropServices;
return FindStringOrdinal(FIND_FROMEND, source, startIndex - count + 1, count, value, value.Length, ignoreCase);
}
-
+
private unsafe int GetHashCodeOfStringCore(ReadOnlySpan<char> source, CompareOptions options)
{
Debug.Assert(!GlobalizationMode.Invariant);
// sort keys, LCMapStringEx treats the output buffer as containing opaque binary data.
// See https://docs.microsoft.com/en-us/windows/desktop/api/winnls/nf-winnls-lcmapstringex.
- byte[] borrowedArr = null;
+ byte[]? borrowedArr = null;
Span<byte> span = sortKeyLength <= 512 ?
stackalloc byte[512] :
(borrowedArr = ArrayPool<byte>.Shared.Rent(sortKeyLength));
fixed (char* char1 = &string1)
fixed (char* char2 = &string2)
{
- // Use the OS to compare and then convert the result to expected value by subtracting 2
+ // Use the OS to compare and then convert the result to expected value by subtracting 2
return Interop.Kernel32.CompareStringOrdinal(char1, count1, char2, count2, true) - 2;
}
}
Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
- string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
+ string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
fixed (char* pLocaleName = localeName)
fixed (char* pString1 = &MemoryMarshal.GetReference(string1))
Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
- string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
+ string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
fixed (char* pLocaleName = localeName)
fixed (char* pString1 = &MemoryMarshal.GetReference(string1))
Debug.Assert(!lpStringSource.IsEmpty);
Debug.Assert(!lpStringValue.IsEmpty);
- string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
+ string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
fixed (char* pLocaleName = localeName)
fixed (char* pSource = &MemoryMarshal.GetReference(lpStringSource))
_sortHandle);
}
}
-
+
private unsafe int FindString(
uint dwFindNLSStringFlags,
string lpStringSource,
Debug.Assert(lpStringSource != null);
Debug.Assert(lpStringValue != null);
- string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
+ string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
fixed (char* pLocaleName = localeName)
fixed (char* pSource = lpStringSource)
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
- byte [] keyData = null;
+ byte [] keyData;
if (source.Length == 0)
- {
+ {
keyData = Array.Empty<byte>();
}
else
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
private string m_name; // The name used to construct this CompareInfo. Do not rename (binary serialization)
[NonSerialized]
- private string _sortName; // The name that defines our behavior
+ private string _sortName = null!; // The name that defines our behavior
[OptionalField(VersionAdded = 3)]
- private SortVersion m_SortVersion; // Do not rename (binary serialization)
+ private SortVersion? m_SortVersion; // Do not rename (binary serialization)
private int culture; // Do not rename (binary serialization). The fields sole purpose is to support Desktop serialization.
[OnDeserializing]
private void OnDeserializing(StreamingContext ctx)
{
- m_name = null;
+ // TODO-NULLABLE: this becomes null for a brief moment before deserialization
+ // after serialization is finished it is never null
+ m_name = null!;
}
void IDeserializationCallback.OnDeserialization(object sender)
/// and the locale's changed behavior, then you'll get changed behavior, which is like
/// what happens for a version update)
/// </summary>
-
public virtual string Name
{
get
/// than string2, and a number greater than 0 if string1 is greater
/// than string2.
/// </summary>
- public virtual int Compare(string string1, string string2)
+ public virtual int Compare(string? string1, string? string2)
{
return Compare(string1, string2, CompareOptions.None);
}
- public virtual int Compare(string string1, string string2, CompareOptions options)
+ public virtual int Compare(string? string1, string? string2, CompareOptions options)
{
if (options == CompareOptions.OrdinalIgnoreCase)
{
// TODO https://github.com/dotnet/coreclr/issues/13827:
// This method shouldn't be necessary, as we should be able to just use the overload
// that takes two spans. But due to this issue, that's adding significant overhead.
- internal int Compare(ReadOnlySpan<char> string1, string string2, CompareOptions options)
+ internal int Compare(ReadOnlySpan<char> string1, string? string2, CompareOptions options)
{
if (options == CompareOptions.OrdinalIgnoreCase)
{
/// string1 is less than string2, and a number greater than 0 if
/// string1 is greater than string2.
/// </summary>
- public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2)
+ public virtual int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2)
{
return Compare(string1, offset1, length1, string2, offset2, length2, 0);
}
- public virtual int Compare(string string1, int offset1, string string2, int offset2, CompareOptions options)
+ public virtual int Compare(string? string1, int offset1, string? string2, int offset2, CompareOptions options)
{
return Compare(string1, offset1, string1 == null ? 0 : string1.Length - offset1,
string2, offset2, string2 == null ? 0 : string2.Length - offset2, options);
}
- public virtual int Compare(string string1, int offset1, string string2, int offset2)
+ public virtual int Compare(string? string1, int offset1, string? string2, int offset2)
{
return Compare(string1, offset1, string2, offset2, 0);
}
- public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
+ public virtual int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2, CompareOptions options)
{
if (options == CompareOptions.OrdinalIgnoreCase)
{
while (length != 0 && charA <= maxChar && charB <= maxChar)
{
- // Ordinal equals or lowercase equals if the result ends up in the a-z range
+ // Ordinal equals or lowercase equals if the result ends up in the a-z range
if (charA == charB ||
((charA | 0x20) == (charB | 0x20) &&
(uint)((charA | 0x20) - 'a') <= (uint)('z' - 'a')))
IntPtr byteOffset = IntPtr.Zero;
while (length != 0)
{
- // Ordinal equals or lowercase equals if the result ends up in the a-z range
+ // Ordinal equals or lowercase equals if the result ends up in the a-z range
uint valueA = Unsafe.AddByteOffset(ref charA, byteOffset);
uint valueB = Unsafe.AddByteOffset(ref charB, byteOffset);
return CreateSortKey(source, CompareOptions.None);
}
- public override bool Equals(object value)
+ public override bool Equals(object? value)
{
return value is CompareInfo otherCompareInfo
&& Name == otherCompareInfo.Name;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
const int ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY = 100; // max size of keyword or value
const int ICU_ULOC_FULLNAME_CAPACITY = 157; // max size of locale name
const string ICU_COLLATION_KEYWORD = "@collation=";
-
-
+
/// <summary>
/// This method uses the sRealName field (which is initialized by the constructor before this is called) to
/// initialize the rest of the state of CultureData based on the underlying OS globalization library.
}
// Replace the ICU collation keyword with an _
+ Debug.Assert(_sWindowsName != null);
index = _sWindowsName.IndexOf(ICU_COLLATION_KEYWORD, StringComparison.Ordinal);
if (index >= 0)
{
}
_bNeutral = TwoLetterISOCountryName.Length == 0;
-
- _sSpecificCulture = _bNeutral ? LocaleData.GetSpecificCultureName(_sRealName) : _sRealName;
-
+
+ _sSpecificCulture = _bNeutral ? LocaleData.GetSpecificCultureName(_sRealName) : _sRealName;
+
// Remove the sort from sName unless custom culture
if (index > 0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
{
return true;
}
- internal static unsafe bool GetLocaleName(string localeName, out string windowsName)
+ internal static unsafe bool GetLocaleName(string localeName, out string? windowsName)
{
// Get the locale name from ICU
char* buffer = stackalloc char[ICU_ULOC_FULLNAME_CAPACITY];
return true;
}
- internal static unsafe bool GetDefaultLocaleName(out string windowsName)
+ internal static unsafe bool GetDefaultLocaleName(out string? windowsName)
{
// Get the default (system) locale name from ICU
char* buffer = stackalloc char[ICU_ULOC_FULLNAME_CAPACITY];
windowsName = new string(buffer); // the name passed to subsequent ICU calls
return true;
}
-
+
private string GetLocaleInfo(LocaleStringData type)
{
Debug.Assert(!GlobalizationMode.Invariant);
-
+
Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo] Expected _sWindowsName to be populated already");
return GetLocaleInfo(_sWindowsName, type);
}
// returning 0 will cause the first supported calendar to be returned, which is the preferred calendar
return 0;
}
-
+
int value = 0;
bool result = Interop.Globalization.GetLocaleInfoInt(_sWindowsName, (uint)type, ref value);
return new string[] { format };
}
- private static CultureData GetCultureDataFromRegionName(string regionName)
+ private static CultureData? GetCultureDataFromRegionName(string? regionName)
{
// no support to lookup by region name, other than the hard-coded list in CultureData
return null;
return new CultureInfo(cultureName)._cultureData.GetLocaleInfo(cultureName, LocaleStringData.LocalizedDisplayName);
}
- private static string GetRegionDisplayName(string isoCountryCode)
+ private static string? GetRegionDisplayName(string? isoCountryCode)
{
// use the fallback which is to return NativeName
return null;
return result.Slice(0, resultPos).ToString();
}
-
- private static string LCIDToLocaleName(int culture)
+
+ private static string? LCIDToLocaleName(int culture)
{
Debug.Assert(!GlobalizationMode.Invariant);
private static int LocaleNameToLCID(string cultureName)
{
Debug.Assert(!GlobalizationMode.Invariant);
-
+
int lcid = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.Lcid);
- return lcid == -1 ? CultureInfo.LOCALE_CUSTOM_UNSPECIFIED : lcid;
+ return lcid == -1 ? CultureInfo.LOCALE_CUSTOM_UNSPECIFIED : lcid;
}
-
+
private static int GetAnsiCodePage(string cultureName)
{
int ansiCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.AnsiCodePage);
- return ansiCodePage == -1 ? CultureData.Invariant.ANSICodePage : ansiCodePage;
+ return ansiCodePage == -1 ? CultureData.Invariant.ANSICodePage : ansiCodePage;
}
private static int GetOemCodePage(string cultureName)
{
int oemCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.OemCodePage);
- return oemCodePage == -1 ? CultureData.Invariant.OEMCodePage : oemCodePage;
+ return oemCodePage == -1 ? CultureData.Invariant.OEMCodePage : oemCodePage;
}
private static int GetMacCodePage(string cultureName)
{
int macCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.MacCodePage);
- return macCodePage == -1 ? CultureData.Invariant.MacCodePage : macCodePage;
+ return macCodePage == -1 ? CultureData.Invariant.MacCodePage : macCodePage;
}
private static int GetEbcdicCodePage(string cultureName)
{
int ebcdicCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.EbcdicCodePage);
- return ebcdicCodePage == -1 ? CultureData.Invariant.EBCDICCodePage : ebcdicCodePage;
+ return ebcdicCodePage == -1 ? CultureData.Invariant.EBCDICCodePage : ebcdicCodePage;
}
private static int GetGeoId(string cultureName)
{
int geoId = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.GeoId);
- return geoId == -1 ? CultureData.Invariant.GeoId : geoId;
+ return geoId == -1 ? CultureData.Invariant.GeoId : geoId;
}
-
+
private static int GetDigitSubstitution(string cultureName)
{
int digitSubstitution = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.DigitSubstitution);
- return digitSubstitution == -1 ? (int) DigitShapes.None : digitSubstitution;
+ return digitSubstitution == -1 ? (int) DigitShapes.None : digitSubstitution;
}
private static string GetThreeLetterWindowsLanguageName(string cultureName)
{
- string langName = LocaleData.GetThreeLetterWindowsLanguageName(cultureName);
- return langName == null ? "ZZZ" /* default lang name */ : langName;
+ return LocaleData.GetThreeLetterWindowsLanguageName(cultureName) ?? "ZZZ" /* default lang name */;
}
private static CultureInfo[] EnumCultures(CultureTypes types)
{
Debug.Assert(!GlobalizationMode.Invariant);
-
+
if ((types & (CultureTypes.NeutralCultures | CultureTypes.SpecificCultures)) == 0)
{
return Array.Empty<CultureInfo>();
}
-
+
int bufferLength = Interop.Globalization.GetLocales(null, 0);
if (bufferLength <= 0)
{
return Array.Empty<CultureInfo>();
}
-
+
char [] chars = new char[bufferLength];
-
+
bufferLength = Interop.Globalization.GetLocales(chars, bufferLength);
if (bufferLength <= 0)
{
return Array.Empty<CultureInfo>();
}
-
- bool enumNeutrals = (types & CultureTypes.NeutralCultures) != 0;
- bool enumSpecificss = (types & CultureTypes.SpecificCultures) != 0;
-
+
+ bool enumNeutrals = (types & CultureTypes.NeutralCultures) != 0;
+ bool enumSpecificss = (types & CultureTypes.SpecificCultures) != 0;
+
List<CultureInfo> list = new List<CultureInfo>();
- if (enumNeutrals)
+ if (enumNeutrals)
{
list.Add(CultureInfo.InvariantCulture);
}
-
+
int index = 0;
while (index < bufferLength)
{
list.Add(ci);
}
}
-
+
index += length;
}
-
+
return list.ToArray();
}
-
+
private static string GetConsoleFallbackName(string cultureName)
{
return LocaleData.GetConsoleUICulture(cultureName);
}
-
+
internal bool IsFramework => false;
-
+
internal bool IsWin32Installed => false;
-
+
internal bool IsReplacementCulture => false;
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
// Wrappers around the GetLocaleInfoEx APIs which handle marshalling the returned
// data as either and Int or string.
- internal static unsafe string GetLocaleInfoEx(string localeName, uint field)
+ internal static unsafe string? GetLocaleInfoEx(string localeName, uint field)
{
// REVIEW: Determine the maximum size for the buffer
const int BUFFER_SIZE = 530;
// Ask OS for data, note that we presume it returns success, so we have to know that
// sWindowsName is valid before calling.
Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
- return GetLocaleInfoExInt(_sWindowsName, lctype);
+ return GetLocaleInfoExInt(_sWindowsName, lctype);
}
private int[] GetLocaleInfo(LocaleGroupingData type)
{
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
return ConvertWin32GroupString(GetLocaleInfoFromLCType(_sWindowsName, (uint)type, UseUserOverride));
}
- private string GetTimeFormatString()
+ private string? GetTimeFormatString()
{
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
return ReescapeWin32String(GetLocaleInfoFromLCType(_sWindowsName, Interop.Kernel32.LOCALE_STIMEFORMAT, UseUserOverride));
}
return ConvertFirstDayOfWeekMonToSun(result);
}
- private string[] GetTimeFormats()
+ private string[]? GetTimeFormats()
{
// Note that this gets overrides for us all the time
Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumTimeFormats] Expected _sWindowsName to be populated by already");
- string[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, 0, UseUserOverride));
+ string[]? result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, 0, UseUserOverride));
return result;
}
- private string[] GetShortTimeFormats()
+ private string[]? GetShortTimeFormats()
{
// Note that this gets overrides for us all the time
Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumShortTimeFormats] Expected _sWindowsName to be populated by already");
- string[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, Interop.Kernel32.TIME_NOSECONDS, UseUserOverride));
+ string[]? result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, Interop.Kernel32.TIME_NOSECONDS, UseUserOverride));
return result;
}
// Enumerate all system cultures and then try to find out which culture has
// region name match the requested region name
- private static CultureData GetCultureDataFromRegionName(string regionName)
+ private static CultureData? GetCultureDataFromRegionName(string regionName)
{
Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert(regionName != null);
#else
// Usually the UI culture shouldn't be different than what we got from WinRT except
// if DefaultThreadCurrentUICulture was set
- CultureInfo ci;
+ CultureInfo? ci;
if (CultureInfo.DefaultThreadCurrentUICulture != null &&
((ci = GetUserDefaultCulture()) != null) &&
}
// Ask OS for data
- string result = GetLocaleInfoEx(localeName, lctype);
- if (result == null)
- {
- // Failed, just use empty string
- result = string.Empty;
- }
-
- return result;
+ // Failed? Just use empty string
+ return GetLocaleInfoEx(localeName, lctype) ?? string.Empty;
}
/// <summary>
///
/// We don't build the stringbuilder unless we find something to change
/// </summary>
- internal static string ReescapeWin32String(string str)
+ internal static string? ReescapeWin32String(string? str)
{
// If we don't have data, then don't try anything
if (str == null)
return null;
}
- StringBuilder result = null;
+ StringBuilder? result = null;
bool inQuote = false;
for (int i = 0; i < str.Length; i++)
return result.ToString();
}
- internal static string[] ReescapeWin32Strings(string[] array)
+ internal static string[]? ReescapeWin32Strings(string[]? array)
{
if (array != null)
{
for (int i = 0; i < array.Length; i++)
{
- array[i] = ReescapeWin32String(array[i]);
+ // only returns null when null is passed
+ array[i] = ReescapeWin32String(array[i])!;
}
}
private struct EnumLocaleData
{
public string regionName;
- public string cultureName;
+ public string? cultureName;
}
// EnumSystemLocaleEx callback.
try
{
string cultureName = new string(lpLocaleString);
- string regionName = GetLocaleInfoEx(cultureName, Interop.Kernel32.LOCALE_SISO3166CTRYNAME);
+ string? regionName = GetLocaleInfoEx(cultureName, Interop.Kernel32.LOCALE_SISO3166CTRYNAME);
if (regionName != null && regionName.Equals(context.regionName, StringComparison.OrdinalIgnoreCase))
{
context.cultureName = cultureName;
}
}
- private static unsafe string[] nativeEnumTimeFormats(string localeName, uint dwFlags, bool useUserOverride)
+ private static unsafe string[]? nativeEnumTimeFormats(string localeName, uint dwFlags, bool useUserOverride)
{
EnumData data = new EnumData();
data.strings = new List<string>();
return Interop.Kernel32.LocaleNameToLCID(cultureName, Interop.Kernel32.LOCALE_ALLOW_NEUTRAL_NAMES);
}
- private static unsafe string LCIDToLocaleName(int culture)
+ private static unsafe string? LCIDToLocaleName(int culture)
{
Debug.Assert(!GlobalizationMode.Invariant);
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
private const int undef = -1;
// Override flag
- private string _sRealName; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
- private string _sWindowsName; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
+ private string _sRealName = null!; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
+ private string? _sWindowsName; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
// Identity
- private string _sName; // locale name (ie: en-us, NO sort info, but could be neutral)
- private string _sParent; // Parent name (which may be a custom locale/culture)
- private string _sLocalizedDisplayName; // Localized pretty name for this locale
- private string _sEnglishDisplayName; // English pretty name for this locale
- private string _sNativeDisplayName; // Native pretty name for this locale
- private string _sSpecificCulture; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort
+ private string? _sName; // locale name (ie: en-us, NO sort info, but could be neutral)
+ private string? _sParent; // Parent name (which may be a custom locale/culture)
+ private string? _sLocalizedDisplayName; // Localized pretty name for this locale
+ private string? _sEnglishDisplayName; // English pretty name for this locale
+ private string? _sNativeDisplayName; // Native pretty name for this locale
+ private string? _sSpecificCulture; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort
// Language
- private string _sISO639Language; // ISO 639 Language Name
- private string _sISO639Language2; // ISO 639 Language Name
- private string _sLocalizedLanguage; // Localized name for this language
- private string _sEnglishLanguage; // English name for this language
- private string _sNativeLanguage; // Native name of this language
- private string _sAbbrevLang; // abbreviated language name (Windows Language Name) ex: ENU
- private string _sConsoleFallbackName; // The culture name for the console fallback UI culture
+ private string? _sISO639Language; // ISO 639 Language Name
+ private string? _sISO639Language2; // ISO 639 Language Name
+ private string? _sLocalizedLanguage; // Localized name for this language
+ private string? _sEnglishLanguage; // English name for this language
+ private string? _sNativeLanguage; // Native name of this language
+ private string? _sAbbrevLang; // abbreviated language name (Windows Language Name) ex: ENU
+ private string? _sConsoleFallbackName; // The culture name for the console fallback UI culture
private int _iInputLanguageHandle=undef;// input language handle
// Region
- private string _sRegionName; // (RegionInfo)
- private string _sLocalizedCountry; // localized country name
- private string _sEnglishCountry; // english country name (RegionInfo)
- private string _sNativeCountry; // native country name
- private string _sISO3166CountryName; // ISO 3166 (RegionInfo), ie: US
- private string _sISO3166CountryName2; // 3 char ISO 3166 country name 2 2(RegionInfo) ex: USA (ISO)
+ private string? _sRegionName; // (RegionInfo)
+ private string? _sLocalizedCountry; // localized country name
+ private string? _sEnglishCountry; // english country name (RegionInfo)
+ private string? _sNativeCountry; // native country name
+ private string? _sISO3166CountryName; // ISO 3166 (RegionInfo), ie: US
+ private string? _sISO3166CountryName2; // 3 char ISO 3166 country name 2 2(RegionInfo) ex: USA (ISO)
private int _iGeoId = undef; // GeoId
// Numbers
- private string _sPositiveSign; // (user can override) positive sign
- private string _sNegativeSign; // (user can override) negative sign
+ private string? _sPositiveSign; // (user can override) positive sign
+ private string? _sNegativeSign; // (user can override) negative sign
// (nfi populates these 5, don't have to be = undef)
private int _iDigits; // (user can override) number of fractional digits
private int _iNegativeNumber; // (user can override) negative number format
- private int[] _waGrouping; // (user can override) grouping of digits
- private string _sDecimalSeparator; // (user can override) decimal separator
- private string _sThousandSeparator; // (user can override) thousands separator
- private string _sNaN; // Not a Number
- private string _sPositiveInfinity; // + Infinity
- private string _sNegativeInfinity; // - Infinity
+ private int[]? _waGrouping; // (user can override) grouping of digits
+ private string? _sDecimalSeparator; // (user can override) decimal separator
+ private string? _sThousandSeparator; // (user can override) thousands separator
+ private string? _sNaN; // Not a Number
+ private string? _sPositiveInfinity; // + Infinity
+ private string? _sNegativeInfinity; // - Infinity
// Percent
private int _iNegativePercent = undef; // Negative Percent (0-3)
private int _iPositivePercent = undef; // Positive Percent (0-11)
- private string _sPercent; // Percent (%) symbol
- private string _sPerMille; // PerMille symbol
+ private string? _sPercent; // Percent (%) symbol
+ private string? _sPerMille; // PerMille symbol
// Currency
- private string _sCurrency; // (user can override) local monetary symbol
- private string _sIntlMonetarySymbol; // international monetary symbol (RegionInfo)
- private string _sEnglishCurrency; // English name for this currency
- private string _sNativeCurrency; // Native name for this currency
+ private string? _sCurrency; // (user can override) local monetary symbol
+ private string? _sIntlMonetarySymbol; // international monetary symbol (RegionInfo)
+ private string? _sEnglishCurrency; // English name for this currency
+ private string? _sNativeCurrency; // Native name for this currency
// (nfi populates these 4, don't have to be = undef)
private int _iCurrencyDigits; // (user can override) # local monetary fractional digits
private int _iCurrency; // (user can override) positive currency format
private int _iNegativeCurrency; // (user can override) negative currency format
- private int[] _waMonetaryGrouping; // (user can override) monetary grouping of digits
- private string _sMonetaryDecimal; // (user can override) monetary decimal separator
- private string _sMonetaryThousand; // (user can override) monetary thousands separator
+ private int[]? _waMonetaryGrouping; // (user can override) monetary grouping of digits
+ private string? _sMonetaryDecimal; // (user can override) monetary decimal separator
+ private string? _sMonetaryThousand; // (user can override) monetary thousands separator
// Misc
private int _iMeasure = undef; // (user can override) system of measurement 0=metric, 1=US (RegionInfo)
- private string _sListSeparator; // (user can override) list separator
+ private string? _sListSeparator; // (user can override) list separator
// Time
- private string _sAM1159; // (user can override) AM designator
- private string _sPM2359; // (user can override) PM designator
- private string _sTimeSeparator;
- private volatile string[] _saLongTimes; // (user can override) time format
- private volatile string[] _saShortTimes; // short time format
- private volatile string[] _saDurationFormats; // time duration format
+ private string? _sAM1159; // (user can override) AM designator
+ private string? _sPM2359; // (user can override) PM designator
+ private string? _sTimeSeparator;
+ private volatile string[]? _saLongTimes; // (user can override) time format
+ private volatile string[]? _saShortTimes; // short time format
+ private volatile string[]? _saDurationFormats; // time duration format
// Calendar specific data
private int _iFirstDayOfWeek = undef; // (user can override) first day of week (gregorian really)
private int _iFirstWeekOfYear = undef; // (user can override) first week of year (gregorian really)
- private volatile CalendarId[] _waCalendars; // all available calendar type(s). The first one is the default calendar
+ private volatile CalendarId[]? _waCalendars; // all available calendar type(s). The first one is the default calendar
// Store for specific data about each calendar
- private CalendarData[] _calendars; // Store for specific calendar data
+ private CalendarData?[]? _calendars; // Store for specific calendar data
// Text information
private int _iReadingLayout = undef; // Reading layout data
s_regionNames = regionNames;
}
- return s_regionNames;
+ return s_regionNames!;
}
}
// Cache of regions we've already looked up
- private static volatile StringCultureDataDictionary s_cachedRegions;
- private static volatile StringStringDictionary s_regionNames;
+ private static volatile StringCultureDataDictionary? s_cachedRegions;
+ private static volatile StringStringDictionary? s_regionNames;
- internal static CultureData GetCultureDataForRegion(string cultureName, bool useUserOverride)
+ internal static CultureData? GetCultureDataForRegion(string? cultureName, bool useUserOverride)
{
// First do a shortcut for Invariant
if (string.IsNullOrEmpty(cultureName))
}
// First check if GetCultureData() can find it (ie: its a real culture)
- CultureData retVal = GetCultureData(cultureName, useUserOverride);
+ CultureData? retVal = GetCultureData(cultureName, useUserOverride);
if (retVal != null && !retVal.IsNeutralCulture)
{
return retVal;
// (Remember this isn't a core clr path where that's not supported)
// If it was neutral remember that so that RegionInfo() can throw the right exception
- CultureData neutral = retVal;
+ CultureData? neutral = retVal;
// Try the hash table next
string hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*');
- StringCultureDataDictionary tempHashTable = s_cachedRegions;
+ StringCultureDataDictionary? tempHashTable = s_cachedRegions;
+
if (tempHashTable == null)
{
// No table yet, make a new one
return s_Invariant;
}
}
- private volatile static CultureData s_Invariant;
+ private volatile static CultureData? s_Invariant;
// Cache of cultures we've already looked up
- private static volatile StringCultureDataDictionary s_cachedCultures;
+ private static volatile StringCultureDataDictionary? s_cachedCultures;
private static readonly object s_lock = new object();
- internal static CultureData GetCultureData(string cultureName, bool useUserOverride)
+ internal static CultureData? GetCultureData(string? cultureName, bool useUserOverride)
{
// First do a shortcut for Invariant
if (string.IsNullOrEmpty(cultureName))
// Try the hash table first
string hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*');
- StringCultureDataDictionary tempHashTable = s_cachedCultures;
+ StringCultureDataDictionary? tempHashTable = s_cachedCultures;
if (tempHashTable == null)
{
// No table yet, make a new one
}
// Not found in the hash table, need to see if we can build one that works for us
- CultureData culture = CreateCultureData(cultureName, useUserOverride);
+ CultureData? culture = CreateCultureData(cultureName, useUserOverride);
if (culture == null)
{
return null;
return name;
}
- private static CultureData CreateCultureData(string cultureName, bool useUserOverride)
+ private static CultureData? CreateCultureData(string cultureName, bool useUserOverride)
{
if (GlobalizationMode.Invariant)
{
private bool InitCompatibilityCultureData()
{
// for compatibility handle the deprecated ids: zh-chs, zh-cht
- string cultureName = _sRealName;
+ string cultureName = _sRealName!;
string fallbackCultureName;
string realCultureName;
/// We'd rather people use the named version since this doesn't allow custom locales
internal static CultureData GetCultureData(int culture, bool bUseUserOverride)
{
- string localeName = null;
- CultureData retVal = null;
+ string? localeName = null;
+ CultureData? retVal = null;
if (culture == CultureInfo.LOCALE_INVARIANT)
{
{
case "zh-CHS":
case "zh-CHT":
- return _sName;
+ // TODO-NULLABLE: dotnet/roslyn#34273
+ return _sName!;
}
- return _sRealName;
+ return _sRealName!;
}
}
if (_sParent == null)
{
// Ask using the real name, so that we get parents of neutrals
- _sParent = GetLocaleInfo(_sRealName, LocaleStringData.ParentName);
+ _sParent = GetLocaleInfo(_sRealName!, LocaleStringData.ParentName);
}
return _sParent;
}
{
// "Azeri (Latin)" + "Azerbaijan" -> "Azeri (Latin, Azerbaijan)"
_sEnglishDisplayName = string.Concat(
- EnglishLanguageName.AsSpan(0, _sEnglishLanguage.Length - 1),
+ EnglishLanguageName.AsSpan(0, _sEnglishLanguage!.Length - 1),
", ",
EnglishCountryName,
")");
{
if (_sAbbrevLang == null)
{
- _sAbbrevLang = GetThreeLetterWindowsLanguageName(_sRealName);
+ _sAbbrevLang = GetThreeLetterWindowsLanguageName(_sRealName!);
}
return _sAbbrevLang;
}
if (CultureInfo.DefaultThreadCurrentUICulture != null &&
((ci = GetUserDefaultCulture()) != null) &&
- !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
+ !CultureInfo.DefaultThreadCurrentUICulture!.Name.Equals(ci.Name))
{
_sLocalizedLanguage = NativeLanguageName;
}
{
if (_iGeoId == undef)
{
- _iGeoId = GetGeoId(_sRealName);
+ _iGeoId = GetGeoId(_sRealName!);
}
return _iGeoId;
}
{
if (_sConsoleFallbackName == null)
{
- _sConsoleFallbackName = GetConsoleFallbackName(_sRealName);
+ _sConsoleFallbackName = GetConsoleFallbackName(_sRealName!);
}
return _sConsoleFallbackName;
}
{
Debug.Assert(!GlobalizationMode.Invariant);
- string[] longTimes = GetTimeFormats();
+ string[]? longTimes = GetTimeFormats();
if (longTimes == null || longTimes.Length == 0)
{
- _saLongTimes = Invariant._saLongTimes;
+ _saLongTimes = Invariant._saLongTimes!;
}
else
{
Debug.Assert(!GlobalizationMode.Invariant);
// Try to get the short times from the OS/culture.dll
- string[] shortTimes = null;
- shortTimes = GetShortTimeFormats();
+ string[]? shortTimes = GetShortTimeFormats();
if (shortTimes == null || shortTimes.Length == 0)
{
if (count == 0)
{
// Failed for some reason, just grab Gregorian from Invariant
- _waCalendars = Invariant._waCalendars;
+ _waCalendars = Invariant._waCalendars!;
}
else
{
// we need the following local variable to avoid returning null
// when another thread creates a new array of CalendarData (above)
// right after we insert the newly created CalendarData (below)
- CalendarData calendarData = _calendars[calendarIndex];
+ CalendarData? calendarData = _calendars[calendarIndex];
// Make sure that calendar has data
if (calendarData == null)
{
{
if (_iDefaultAnsiCodePage == undef)
{
- _iDefaultAnsiCodePage = GetAnsiCodePage(_sRealName);
+ _iDefaultAnsiCodePage = GetAnsiCodePage(_sRealName!);
}
return _iDefaultAnsiCodePage;
}
{
if (_iDefaultOemCodePage == undef)
{
- _iDefaultOemCodePage = GetOemCodePage(_sRealName);
+ _iDefaultOemCodePage = GetOemCodePage(_sRealName!);
}
return _iDefaultOemCodePage;
}
{
if (_iDefaultMacCodePage == undef)
{
- _iDefaultMacCodePage = GetMacCodePage(_sRealName);
+ _iDefaultMacCodePage = GetMacCodePage(_sRealName!);
}
return _iDefaultMacCodePage;
}
{
if (_iDefaultEbcdicCodePage == undef)
{
- _iDefaultEbcdicCodePage = GetEbcdicCodePage(_sRealName);
+ _iDefaultEbcdicCodePage = GetEbcdicCodePage(_sRealName!);
}
return _iDefaultEbcdicCodePage;
}
{
if (_sTimeSeparator == null)
{
- string longTimeFormat = GetTimeFormatString();
+ string? longTimeFormat = GetTimeFormatString();
if (string.IsNullOrEmpty(longTimeFormat))
{
longTimeFormat = LongTimes[0];
Debug.Assert(str != null);
Debug.Assert(start >= 0);
Debug.Assert(end >= 0);
- StringBuilder result = null;
+ StringBuilder? result = null;
for (int i = start; i < str.Length && i <= end; i++)
{
{
if (GlobalizationMode.Invariant || IsInvariantCulture)
{
- nfi._positiveSign = _sPositiveSign;
- nfi._negativeSign = _sNegativeSign;
+ nfi._positiveSign = _sPositiveSign!;
+ nfi._negativeSign = _sNegativeSign!;
- nfi._numberGroupSeparator = _sThousandSeparator;
- nfi._numberDecimalSeparator = _sDecimalSeparator;
+ nfi._numberGroupSeparator = _sThousandSeparator!;
+ nfi._numberDecimalSeparator = _sDecimalSeparator!;
nfi._numberDecimalDigits = _iDigits;
nfi._numberNegativePattern = _iNegativeNumber;
- nfi._currencySymbol = _sCurrency;
- nfi._currencyGroupSeparator = _sMonetaryThousand;
- nfi._currencyDecimalSeparator = _sMonetaryDecimal;
+ nfi._currencySymbol = _sCurrency!;
+ nfi._currencyGroupSeparator = _sMonetaryThousand!;
+ nfi._currencyDecimalSeparator = _sMonetaryDecimal!;
nfi._currencyDecimalDigits = _iCurrencyDigits;
nfi._currencyNegativePattern = _iNegativeCurrency;
nfi._currencyPositivePattern = _iCurrency;
nfi._nativeDigits[i] = char.ToString(digits[i]);
}
+ Debug.Assert(_sRealName != null);
nfi._digitSubstitution = GetDigitSubstitution(_sRealName);
}
// See the LICENSE file in the project root for more information.
#nullable enable
+using System.Diagnostics;
+
namespace System.Globalization
{
public partial class CultureInfo : IFormatProvider
return CultureInfo.InvariantCulture;
CultureInfo cultureInfo;
- string localeName;
+ string? localeName;
if (CultureData.GetDefaultLocaleName(out localeName))
{
+ Debug.Assert(localeName != null);
cultureInfo = GetCultureByName(localeName);
}
else
if (GlobalizationMode.Invariant)
return CultureInfo.InvariantCulture;
- string strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_USER_DEFAULT, Interop.Kernel32.LOCALE_SNAME);
+ string? strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_USER_DEFAULT, Interop.Kernel32.LOCALE_SNAME);
if (strDefault == null)
{
strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_SYSTEM_DEFAULT, Interop.Kernel32.LOCALE_SNAME);
}
// Get our data providing record
- _cultureData = CultureData.GetCultureData(name, useUserOverride);
+ CultureData? cultureData = CultureData.GetCultureData(name, useUserOverride);
- if (_cultureData == null)
+ if (cultureData == null)
{
throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported);
}
+ _cultureData = cultureData;
_name = _cultureData.CultureName;
_isInherited = GetType() != typeof(CultureInfo);
}
throw new ArgumentNullException(nameof(cultureName), SR.ArgumentNull_String);
}
- _cultureData = CultureData.GetCultureData(cultureName, false);
- if (_cultureData == null)
+ CultureData? cultureData = CultureData.GetCultureData(cultureName, false);
+ if (cultureData == null)
{
throw new CultureNotFoundException(nameof(cultureName), cultureName, SR.Argument_CultureNotSupported);
}
+ _cultureData = cultureData;
+
_name = _cultureData.CultureName;
CultureInfo altCulture = GetCultureInfo(textAndCompareCultureName);
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Runtime.Serialization;
namespace System.Globalization
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public class CultureNotFoundException : ArgumentException
{
- private string _invalidCultureName; // unrecognized culture name
+ private string? _invalidCultureName; // unrecognized culture name
private int? _invalidCultureId; // unrecognized culture Lcid
public CultureNotFoundException()
{
}
- public CultureNotFoundException(string message)
+ public CultureNotFoundException(string? message)
: base(message)
{
}
- public CultureNotFoundException(string paramName, string message)
+ public CultureNotFoundException(string? paramName, string? message)
: base(message, paramName)
{
}
- public CultureNotFoundException(string message, Exception innerException)
+ public CultureNotFoundException(string? message, Exception? innerException)
: base(message, innerException)
{
}
- public CultureNotFoundException(string paramName, string invalidCultureName, string message)
+ public CultureNotFoundException(string? paramName, string? invalidCultureName, string? message)
: base(message, paramName)
{
_invalidCultureName = invalidCultureName;
}
- public CultureNotFoundException(string message, string invalidCultureName, Exception innerException)
+ public CultureNotFoundException(string? message, string? invalidCultureName, Exception? innerException)
: base(message, innerException)
{
_invalidCultureName = invalidCultureName;
}
- public CultureNotFoundException(string message, int invalidCultureId, Exception innerException)
+ public CultureNotFoundException(string? message, int invalidCultureId, Exception? innerException)
: base(message, innerException)
{
_invalidCultureId = invalidCultureId;
}
- public CultureNotFoundException(string paramName, int invalidCultureId, string message)
+ public CultureNotFoundException(string? paramName, int invalidCultureId, string? message)
: base(message, paramName)
{
_invalidCultureId = invalidCultureId;
get { return _invalidCultureId; }
}
- public virtual string InvalidCultureName
+ public virtual string? InvalidCultureName
{
get { return _invalidCultureName; }
}
}
}
- private string FormatedInvalidCultureId
+ private string? FormattedInvalidCultureId
{
get
{
string s = base.Message;
if (_invalidCultureId != null || _invalidCultureName != null)
{
- string valueMessage = SR.Format(SR.Argument_CultureInvalidIdentifier, FormatedInvalidCultureId);
+ string valueMessage = SR.Format(SR.Argument_CultureInvalidIdentifier, FormattedInvalidCultureId);
if (s == null)
{
return valueMessage;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
private CultureData _cultureData;
// The culture name used to create this DTFI.
- private string _name = null;
+ private string? _name = null;
// The language name of the culture used to create this DTFI.
- private string _langName = null;
+ private string? _langName = null;
// CompareInfo usually used by the parser.
- private CompareInfo _compareInfo = null;
+ private CompareInfo? _compareInfo = null;
// Culture matches current DTFI. mainly used for string comparisons during parsing.
- private CultureInfo _cultureInfo = null;
+ private CultureInfo? _cultureInfo = null;
- private string amDesignator = null;
- private string pmDesignator = null;
+ private string? amDesignator = null;
+ private string? pmDesignator = null;
- private string dateSeparator = null; // derived from short date (whidbey expects, arrowhead doesn't)
+ private string? dateSeparator = null; // derived from short date (whidbey expects, arrowhead doesn't)
- private string generalShortTimePattern = null; // short date + short time (whidbey expects, arrowhead doesn't)
+ private string? generalShortTimePattern = null; // short date + short time (whidbey expects, arrowhead doesn't)
- private string generalLongTimePattern = null; // short date + long time (whidbey expects, arrowhead doesn't)
+ private string? generalLongTimePattern = null; // short date + long time (whidbey expects, arrowhead doesn't)
- private string timeSeparator = null; // derived from long time (whidbey expects, arrowhead doesn't)
- private string monthDayPattern = null;
- private string dateTimeOffsetPattern = null;
+ private string? timeSeparator = null; // derived from long time (whidbey expects, arrowhead doesn't)
+ private string? monthDayPattern = null;
+ private string? dateTimeOffsetPattern = null;
private const string rfc1123Pattern = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";
private const string sortableDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss";
private const string universalSortableDateTimePattern = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'";
- private Calendar calendar = null;
+ private Calendar calendar = null!;
private int firstDayOfWeek = -1;
private int calendarWeekRule = -1;
- private string fullDateTimePattern = null; // long date + long time (whidbey expects, arrowhead doesn't)
+ private string? fullDateTimePattern = null; // long date + long time (whidbey expects, arrowhead doesn't)
- private string[] abbreviatedDayNames = null;
+ private string[]? abbreviatedDayNames = null;
- private string[] m_superShortDayNames = null;
+ private string[]? m_superShortDayNames = null;
- private string[] dayNames = null;
- private string[] abbreviatedMonthNames = null;
- private string[] monthNames = null;
+ private string[]? dayNames = null;
+ private string[]? abbreviatedMonthNames = null;
+ private string[]? monthNames = null;
// Cache the genitive month names that we retrieve from the data table.
- private string[] genitiveMonthNames = null;
+ private string[]? genitiveMonthNames = null;
// Cache the abbreviated genitive month names that we retrieve from the data table.
- private string[] m_genitiveAbbreviatedMonthNames = null;
+ private string[]? m_genitiveAbbreviatedMonthNames = null;
// Cache the month names of a leap year that we retrieve from the data table.
- private string[] leapYearMonthNames = null;
+ private string[]? leapYearMonthNames = null;
// For our "patterns" arrays we have 2 variables, a string and a string[]
//
// When we initially construct our string[], we set the string to string[0]
// The "default" Date/time patterns
- private string longDatePattern = null;
- private string shortDatePattern = null;
- private string yearMonthPattern = null;
- private string longTimePattern = null;
- private string shortTimePattern = null;
+ private string? longDatePattern = null;
+ private string? shortDatePattern = null;
+ private string? yearMonthPattern = null;
+ private string? longTimePattern = null;
+ private string? shortTimePattern = null;
- private string[] allYearMonthPatterns = null;
+ private string[]? allYearMonthPatterns = null;
- private string[] allShortDatePatterns = null;
- private string[] allLongDatePatterns = null;
- private string[] allShortTimePatterns = null;
- private string[] allLongTimePatterns = null;
+ private string[]? allShortDatePatterns = null;
+ private string[]? allLongDatePatterns = null;
+ private string[]? allShortTimePatterns = null;
+ private string[]? allLongTimePatterns = null;
// Cache the era names for this DateTimeFormatInfo instance.
- private string[] m_eraNames = null;
- private string[] m_abbrevEraNames = null;
- private string[] m_abbrevEnglishEraNames = null;
+ private string[]? m_eraNames = null;
+ private string[]? m_abbrevEraNames = null;
+ private string[]? m_abbrevEnglishEraNames = null;
- private CalendarId[] optionalCalendars = null;
+ private CalendarId[]? optionalCalendars = null;
private const int DEFAULT_ALL_DATETIMES_SIZE = 132;
/// <summary>
/// Returns the current culture's DateTimeFormatInfo.
/// </summary>
-
public static DateTimeFormatInfo CurrentInfo
{
get
System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture;
if (!culture._isInherited)
{
- DateTimeFormatInfo info = culture._dateTimeInfo;
+ DateTimeFormatInfo? info = culture._dateTimeInfo;
if (info != null)
{
return info;
}
}
- return (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo));
+ return (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo))!;
}
}
- public static DateTimeFormatInfo GetInstance(IFormatProvider provider) =>
+ public static DateTimeFormatInfo GetInstance(IFormatProvider? provider) =>
provider == null ? CurrentInfo :
provider is CultureInfo cultureProvider && !cultureProvider._isInherited ? cultureProvider.DateTimeFormat :
provider is DateTimeFormatInfo info ? info :
provider.GetFormat(typeof(DateTimeFormatInfo)) is DateTimeFormatInfo info2 ? info2 :
CurrentInfo; // Couldn't get anything, just use currentInfo as fallback
- public object GetFormat(Type formatType)
+ public object? GetFormat(Type? formatType)
{
return formatType == typeof(DateTimeFormatInfo) ? this : null;
}
for (int i = 0; i < EraNames.Length; i++)
{
// Compare the era name in a case-insensitive way for the appropriate culture.
- if (m_eraNames[i].Length > 0)
+ if (m_eraNames![i].Length > 0)
{
if (Culture.CompareInfo.Compare(eraName, m_eraNames[i], CompareOptions.IgnoreCase) == 0)
{
for (int i = 0; i < AbbreviatedEraNames.Length; i++)
{
// Compare the abbreviated era name in a case-insensitive way for the appropriate culture.
- if (Culture.CompareInfo.Compare(eraName, m_abbrevEraNames[i], CompareOptions.IgnoreCase) == 0)
+ if (Culture.CompareInfo.Compare(eraName, m_abbrevEraNames![i], CompareOptions.IgnoreCase) == 0)
{
return i + 1;
}
{
// this comparison should use the InvariantCulture. The English name could have linguistically
// interesting characters.
- if (CompareInfo.Invariant.Compare(eraName, m_abbrevEnglishEraNames[i], CompareOptions.IgnoreCase) == 0)
+ if (CompareInfo.Invariant.Compare(eraName, m_abbrevEnglishEraNames![i], CompareOptions.IgnoreCase) == 0)
{
return i + 1;
}
// If that ever changes, the code has to be changed.
if ((--era) < EraNames.Length && (era >= 0))
{
- return m_eraNames[era];
+ return m_eraNames![era];
}
throw new ArgumentOutOfRangeException(nameof(era), era, SR.ArgumentOutOfRange_InvalidEraValue);
{
era = Calendar.CurrentEraValue;
}
- if ((--era) < m_abbrevEraNames.Length && (era >= 0))
+ if ((--era) < m_abbrevEraNames!.Length && (era >= 0))
{
return m_abbrevEraNames[era];
}
value,
SR.Format(SR.ArgumentOutOfRange_Range, CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
}
-
+
calendarWeekRule = (int)value;
}
}
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
}
-
+
CheckNullValue(value, value.Length);
ClearTokenHashTable();
/// </summary>
internal string InternalGetMonthName(int month, MonthNameStyles style, bool abbreviated)
{
- string[] monthNamesArray = null;
+ string[] monthNamesArray;
switch (style)
{
case MonthNameStyles.Genitive:
public string[] GetAllDateTimePatterns(char format)
{
- string[] result = null;
+ string[] result;
switch (format)
{
}
// Decimal separator used by positive TimeSpan pattern
- private string _decimalSeparator;
+ private string? _decimalSeparator;
internal string DecimalSeparator
{
get
{
if (_decimalSeparator == null)
{
- CultureData cultureDataWithoutUserOverrides = _cultureData.UseUserOverride ?
+ CultureData? cultureDataWithoutUserOverrides = _cultureData.UseUserOverride ?
CultureData.GetCultureData(_cultureData.CultureName, false) :
_cultureData;
_decimalSeparator = new NumberFormatInfo(cultureDataWithoutUserOverrides).NumberDecimalSeparator;
}
// Positive TimeSpan Pattern
- private string _fullTimeSpanPositivePattern;
+ private string? _fullTimeSpanPositivePattern;
internal string FullTimeSpanPositivePattern
{
get
}
// Negative TimeSpan Pattern
- private string _fullTimeSpanNegativePattern;
+ private string? _fullTimeSpanNegativePattern;
internal string FullTimeSpanNegativePattern
{
get
}
// DateTimeFormatInfo tokenizer. This is used by DateTime.Parse() to break input string into tokens.
- private TokenHashValue[] _dtfiTokenHash;
+ private TokenHashValue[]? _dtfiTokenHash;
private const int TOKEN_HASH_SIZE = 199;
private const int SECOND_PRIME = 197;
internal TokenHashValue[] CreateTokenHashTable()
{
- TokenHashValue[] temp = _dtfiTokenHash;
+ TokenHashValue[]? temp = _dtfiTokenHash;
if (temp == null)
{
temp = new TokenHashValue[TOKEN_HASH_SIZE];
InsertHash(temp, dateSeparatorOrTimeZoneOffset, TokenType.SEP_DateOrOffset, 0);
}
- string[] dateWords = null;
- DateTimeFormatInfoScanner scanner = null;
-
// We need to rescan the date words since we're always synthetic
- scanner = new DateTimeFormatInfoScanner();
- dateWords = scanner.GetDateWordsOfDTFI(this);
+ DateTimeFormatInfoScanner scanner = new DateTimeFormatInfoScanner();
+ string[]? dateWords = scanner.GetDateWordsOfDTFI(this);
// Ensure the formatflags is initialized.
DateTimeFormatFlags flag = FormatFlags;
int remaining = str.Length - str.Index;
int i = 0;
- TokenHashValue[] hashTable = _dtfiTokenHash;
+ TokenHashValue[]? hashTable = _dtfiTokenHash;
if (hashTable == null)
{
hashTable = CreateTokenHashTable();
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
return new FormatException(SR.Format(SR.GetResourceString(result.failureMessageID), new string(result.originalDateTimeString), result.failureMessageFormatArgument));
default:
Debug.Fail("Unknown DateTimeParseFailure: " + result.failure.ToString());
- return null;
+ return null!;
}
}
internal ParseFailureKind failure;
internal string failureMessageID;
- internal object failureMessageFormatArgument;
+ internal object? failureMessageFormatArgument;
internal string failureArgumentName;
internal ReadOnlySpan<char> originalDateTimeString;
internal ReadOnlySpan<char> failedFormatSpecifier;
this.failureMessageFormatArgument = null;
}
- internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument)
+ internal void SetFailure(ParseFailureKind failure, string failureMessageID, object? failureMessageFormatArgument)
{
this.failure = failure;
this.failureMessageID = failureMessageID;
this.failureMessageFormatArgument = failureMessageFormatArgument;
}
- internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument, string failureArgumentName)
+ internal void SetFailure(ParseFailureKind failure, string failureMessageID, object? failureMessageFormatArgument, string failureArgumentName)
{
this.failure = failure;
this.failureMessageID = failureMessageID;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
namespace System.Globalization
{
// This class represents a starting/ending time for a period of daylight saving time.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Diagnostics;
public override int GetEra(DateTime time) => ADEra;
- public override int[]? Eras => new int[] { ADEra };
+ public override int[] Eras => new int[] { ADEra };
/// <summary>
/// Returns the month part of the specified DateTime.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System;
using System.Threading;
// be affected by the DateTime.MinValue;
internal int maxEraYear; // Max year value in this era. (== the year length of the era + 1)
- internal string eraName; // The era name
- internal string abbrevEraName; // Abbreviated Era Name
- internal string englishEraName; // English era name
+ internal string? eraName; // The era name
+ internal string? abbrevEraName; // Abbreviated Era Name
+ internal string? englishEraName; // English era name
internal EraInfo(int era, int startYear, int startMonth, int startDay, int yearOffset, int minEraYear, int maxEraYear)
{
internal Calendar m_Cal;
internal EraInfo[] m_EraInfo;
- internal int[] m_eras = null;
+ internal int[]? m_eras = null;
// Construct an instance of gregorian calendar.
}
}
}
-
public override int GetEra(DateTime time) => HebrewEra;
- public override int[]? Eras => new int[] { HebrewEra };
+ public override int[] Eras => new int[] { HebrewEra };
public override int GetMonth(DateTime time)
{
}
}
}
-
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Text;
using System.Diagnostics;
Digit200_300 = 1,
Digit100 = 2,
Digit10 = 3, // 10 ~ 90
- Digit1 = 4, // 1, 2, 3, 4, 5, 8,
+ Digit1 = 4, // 1, 2, 3, 4, 5, 8,
Digit6_7 = 5,
Digit7 = 6,
Digit9 = 7,
new HebrewValue(HebrewToken.Digit1, 8) , // '\x05d7
new HebrewValue(HebrewToken.Digit9, 9) , // '\x05d8
new HebrewValue(HebrewToken.Digit10, 10) , // '\x05d9; // Hebrew Letter Yod
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da;
+ new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da;
new HebrewValue(HebrewToken.Digit10, 20) , // '\x05db; // Hebrew Letter Kaf
new HebrewValue(HebrewToken.Digit10, 30) , // '\x05dc; // Hebrew Letter Lamed
new HebrewValue(HebrewToken.Invalid, -1) , // '\x05dd;
END = 100, // A terminial state is reached.
}
- //
+ //
// The state machine for Hebrew number pasing.
//
private static readonly HS[] s_numberPasingState =
private const int HebrewTokenCount = 10;
////////////////////////////////////////////////////////////////////////
- //
+ //
// Actions:
// Parse the Hebrew number by passing one character at a time.
// The state between characters are maintained at HebrewNumberPasingContext.
return HijriEra;
}
- public override int[]? Eras => new int[] { HijriEra };
+ public override int[] Eras => new int[] { HijriEra };
public override int GetMonth(DateTime time)
{
{
throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
}
-
+
return new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond));
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using static System.Globalization.GregorianCalendar;
namespace System.Globalization
int correction = GetWeekday(jan4.DayOfWeek) + 3;
int ordinal = (week * 7) + GetWeekday(dayOfWeek) - correction;
-
+
return new DateTime(year, month: 1, day: 1).AddDays(ordinal - 1);
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
namespace System.Globalization
/// is enabled.
///
/// To match Windows behavior, we walk the string ourselves looking for these
- /// bad characters so we can continue to throw ArgumentException in these cases.
+ /// bad characters so we can continue to throw ArgumentException in these cases.
/// </summary>
private static unsafe void CheckInvalidIdnCharacters(char* s, int count, uint flags, string paramName)
{
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
using System.Runtime.InteropServices;
int lastError = Marshal.GetLastWin32Error();
throw new ArgumentException(
- lastError == Interop.Errors.ERROR_INVALID_NAME ? SR.Argument_IdnIllegalName :
+ lastError == Interop.Errors.ERROR_INVALID_NAME ? SR.Argument_IdnIllegalName :
(unicode ? SR.Argument_InvalidCharSequenceNoIndex : SR.Argument_IdnBadPunycode),
unicode ? "unicode" : "ascii");
}
}
}
-
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
// This file contains the IDN functions and implementation.
//
// This allows encoding of non-ASCII domain names in a "punycode" form,
}
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
return
obj is IdnMapping that &&
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
namespace System.Globalization
{
internal class InternalGlobalizationHelper
return null;
}
- string[] eraNames;
+ string[]? eraNames;
if (!CalendarData.EnumCalendarInfo("ja-JP", CalendarId.JAPAN, CalendarDataType.EraNames, out eraNames))
{
return null;
}
- string[] abbrevEnglishEraNames;
+ string[]? abbrevEnglishEraNames;
if (!CalendarData.EnumCalendarInfo("en", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames))
{
return null;
}
eras.Add(new EraInfo(i, dt.Year, dt.Month, dt.Day, dt.Year - 1, 1, lastMaxYear - dt.Year + 1,
- eraNames[i], GetAbbreviatedEraName(eraNames, i), abbrevEnglishEraNames[i]));
+ eraNames![i], GetAbbreviatedEraName(eraNames, i), abbrevEnglishEraNames![i]));
lastMaxYear = dt.Year;
}
{
return _helper.AddYears(time, years);
}
-
+
public override int GetDaysInMonth(int year, int month, int era)
{
return _helper.GetDaysInMonth(year, month, era);
}
- public override int[]? Eras => _helper.Eras;
+ public override int[] Eras => _helper.Eras;
/// <summary>
/// Return the various era strings
for (int i = 0; i < eras.Length; i++)
{
// Strings are in chronological order, eras are backwards order.
- eraNames[i] = eras[eras.Length - i - 1].eraName;
+ eraNames[i] = eras[eras.Length - i - 1].eraName!;
}
return eraNames;
for (int i = 0; i < eras.Length; i++)
{
// Strings are in chronological order, eras are backwards order.
- erasAbbrev[i] = eras[eras.Length - i - 1].abbrevEraName;
+ erasAbbrev[i] = eras[eras.Length - i - 1].abbrevEraName!;
}
return erasAbbrev;
for (int i = 0; i < eras.Length; i++)
{
// Strings are in chronological order, eras are backwards order.
- erasEnglish[i] = eras[eras.Length - i - 1].englishEraName;
+ erasEnglish[i] = eras[eras.Length - i - 1].englishEraName!;
}
return erasEnglish;
public override DateTime MinSupportedDateTime => s_minDate;
public override DateTime MaxSupportedDateTime => s_maxDate;
-
+
protected override int DaysInYearBeforeMinSupportedYear
{
get
internal override CalendarId ID => CalendarId.JAPANESELUNISOLAR;
- public override int[]? Eras => _helper.Eras;
+ public override int[] Eras => _helper.Eras;
}
}
return GetDatePart(time.Ticks, DatePartMonth);
}
- public override int[]? Eras => new int[] { JulianEra };
+ public override int[] Eras => new int[] { JulianEra };
public override int GetMonthsInYear(int year, int era)
{
return _helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era);
}
- public override int[]? Eras => _helper.Eras;
+ public override int[] Eras => _helper.Eras;
private const int DefaultTwoDigitYearMax = 4362;
internal override CalendarId ID => CalendarId.KOREANLUNISOLAR;
- public override int[]? Eras => new int[] { GregorianEra };
+ public override int[] Eras => new int[] { GregorianEra };
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
-// This file contains the handling of Windows OS specific culture features.
+// This file contains the handling of Windows OS specific culture features.
namespace System.Globalization
{
OemCodePage = 2,
MacCodePage = 3,
EbcdicCodePage = 4,
- GeoId = 5,
- DigitSubstitution = 6,
- SpecificLocaleIndex = 7,
+ GeoId = 5,
+ DigitSubstitution = 6,
+ SpecificLocaleIndex = 7,
ConsoleLocaleIndex = 8
}
-
+
internal partial class LocaleData
{
// this is done rather than using a large readonly array of strings to avoid
"zh-tw_radstr" + // 40404 - 4265
"zu" + // 00035 - 4277
"zu-za"; // 00435 - 4279
-
+
// c_threeLetterWindowsLanguageName is string containing 3-letter Windows language names
- // every 3-characters entry is matching locale name entry in c_localeNames
-
+ // every 3-characters entry is matching locale name entry in c_localeNames
+
private const string c_threeLetterWindowsLanguageName =
"ZZZ" + // aa
"ZZZ" + // aa-dj
4279, // 863 - zu-za
4284
};
-
+
private const int NUMERIC_LOCALE_DATA_COUNT_PER_ROW = 9;
// s_nameIndexToNumericData is mapping from index in s_localeNamesIndices to locale data.
// each row in the table will have the following data:
0x435 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 863 , 863 , // 863 - zu-za
};
- // s_lcids list all supported lcids. used to binary search and we use the index of the matched lcid to
+ // s_lcids list all supported lcids. used to binary search and we use the index of the matched lcid to
// get the index in s_localeNamesIndices using s_lcidToCultureNameIndices
private static readonly int[] s_lcids = new int[]
{
0x41404, // 445 - 4195
0x50804, // 446 - 4115
0x51004 // 447 - 4224
- };
+ };
// each element in s_lcidToCultureNameIndices is index to s_localeNamesIndices
private static readonly int[] s_lcidToCultureNameIndices = new int[]
{
845 , // 446 - 50804 - 4115
857 // 447 - 51004 - 4224
};
-
- internal static string LCIDToLocaleName(int culture)
+
+ internal static string? LCIDToLocaleName(int culture)
{
int left = 0;
int right = s_lcids.Length - 1;
{
int indexToLocaleNamesIndices = s_lcidToCultureNameIndices[index];
Debug.Assert(indexToLocaleNamesIndices < s_localeNamesIndices.Length - 1);
-
- return c_localeNames.Substring(s_localeNamesIndices[indexToLocaleNamesIndices],
- s_localeNamesIndices[indexToLocaleNamesIndices + 1] -
+
+ return c_localeNames.Substring(s_localeNamesIndices[indexToLocaleNamesIndices],
+ s_localeNamesIndices[indexToLocaleNamesIndices + 1] -
s_localeNamesIndices[indexToLocaleNamesIndices]);
}
else if (culture < s_lcids[index])
int index = SearchCultureName(cultureName);
if (index < 0)
{
- return -1;
+ return -1;
}
-
- Debug.Assert((s_localeNamesIndices.Length-1 == (s_nameIndexToNumericData.Length/NUMERIC_LOCALE_DATA_COUNT_PER_ROW)) &&
+
+ Debug.Assert((s_localeNamesIndices.Length-1 == (s_nameIndexToNumericData.Length/NUMERIC_LOCALE_DATA_COUNT_PER_ROW)) &&
index < s_localeNamesIndices.Length);
-
+
return s_nameIndexToNumericData[index * NUMERIC_LOCALE_DATA_COUNT_PER_ROW + (int) part];
}
-
- internal static string GetThreeLetterWindowsLanguageName(string cultureName)
+
+ internal static string? GetThreeLetterWindowsLanguageName(string cultureName)
{
int index = SearchCultureName(cultureName);
if (index < 0)
{
return null;
}
-
+
Debug.Assert(s_localeNamesIndices.Length-1 == (c_threeLetterWindowsLanguageName.Length / 3));
- return c_threeLetterWindowsLanguageName.Substring(index * 3, 3);
+ return c_threeLetterWindowsLanguageName.Substring(index * 3, 3);
}
-
+
internal static string GetLocaleDataMappedCulture(string cultureName, LocaleDataParts part)
{
int indexToIndicesTable = GetLocaleDataNumericPart(cultureName, part);
{
return ""; // fallback to invariant
}
-
+
Debug.Assert(indexToIndicesTable < s_localeNamesIndices.Length-1);
-
- return c_localeNames.Substring(s_localeNamesIndices[indexToIndicesTable],
+
+ return c_localeNames.Substring(s_localeNamesIndices[indexToIndicesTable],
s_localeNamesIndices[indexToIndicesTable+1] - s_localeNamesIndices[indexToIndicesTable]);
}
-
+
internal static string GetSpecificCultureName(string cultureName)
{
return GetLocaleDataMappedCulture(cultureName, LocaleDataParts.SpecificLocaleIndex);
}
-
+
internal static string GetConsoleUICulture(string cultureName)
{
return GetLocaleDataMappedCulture(cultureName, LocaleDataParts.ConsoleLocaleIndex);
}
-
+
// SearchCultureName will binary search c_localeNames using s_localeNamesIndices.
- // return index in s_localeNamesIndices, or -1 if it fail finding any match
+ // return index in s_localeNamesIndices, or -1 if it fail finding any match
private static int SearchCultureName(string name)
{
int left = 0;
// couldn't find culture name
return -1;
}
-
+
// optimized to avoid parameters checking
private static int CompareOrdinal(string s1, string s2, int index, int length)
{
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
using System.Text;
{
if (GlobalizationMode.Invariant)
{
- // In Invariant mode we assume all characters are normalized.
+ // In Invariant mode we assume all characters are normalized.
// This is because we don't support any linguistic operation on the strings
return true;
}
{
if (GlobalizationMode.Invariant)
{
- // In Invariant mode we assume all characters are normalized.
+ // In Invariant mode we assume all characters are normalized.
// This is because we don't support any linguistic operation on the strings
return strInput;
}
for (int i = 0; i < s.Length; i++)
{
char c = s[i];
-
+
if (c < '\ud800')
{
continue;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
{
if (GlobalizationMode.Invariant)
{
- // In Invariant mode we assume all characters are normalized.
+ // In Invariant mode we assume all characters are normalized.
// This is because we don't support any linguistic operation on the strings
return true;
}
Debug.Assert(strInput != null);
// The only way to know if IsNormalizedString failed is through checking the Win32 last error
- // IsNormalizedString pinvoke has SetLastError attribute property which will set the last error
+ // IsNormalizedString pinvoke has SetLastError attribute property which will set the last error
// to 0 (ERROR_SUCCESS) before executing the calls.
bool result = Interop.Normaliz.IsNormalizedString((int)normalizationForm, strInput, strInput.Length);
case Interop.Errors.ERROR_INVALID_PARAMETER:
case Interop.Errors.ERROR_NO_UNICODE_TRANSLATION:
- if (normalizationForm != NormalizationForm.FormC &&
- normalizationForm != NormalizationForm.FormD &&
- normalizationForm != NormalizationForm.FormKC &&
+ if (normalizationForm != NormalizationForm.FormC &&
+ normalizationForm != NormalizationForm.FormD &&
+ normalizationForm != NormalizationForm.FormKC &&
normalizationForm != NormalizationForm.FormKD)
{
throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm));
{
if (GlobalizationMode.Invariant)
{
- // In Invariant mode we assume all characters are normalized.
+ // In Invariant mode we assume all characters are normalized.
// This is because we don't support any linguistic operation on the strings
return strInput;
}
Debug.Assert(strInput != null);
// we depend on Win32 last error when calling NormalizeString
- // NormalizeString pinvoke has SetLastError attribute property which will set the last error
+ // NormalizeString pinvoke has SetLastError attribute property which will set the last error
// to 0 (ERROR_SUCCESS) before executing the calls.
// Guess our buffer size first
{
if (lastError == Interop.Errors.ERROR_INVALID_PARAMETER)
{
- if (normalizationForm != NormalizationForm.FormC &&
- normalizationForm != NormalizationForm.FormD &&
- normalizationForm != NormalizationForm.FormKC &&
+ if (normalizationForm != NormalizationForm.FormC &&
+ normalizationForm != NormalizationForm.FormD &&
+ normalizationForm != NormalizationForm.FormKC &&
normalizationForm != NormalizationForm.FormKD)
{
throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm));
if (iLength == 0) return string.Empty;
// Someplace to stick our buffer
- char[] cBuffer = null;
+ char[] cBuffer;
for (;;)
{
// (re)allocation buffer and normalize string
cBuffer = new char[iLength];
- // NormalizeString pinvoke has SetLastError attribute property which will set the last error
+ // NormalizeString pinvoke has SetLastError attribute property which will set the last error
// to 0 (ERROR_SUCCESS) before executing the calls.
iLength = Interop.Normaliz.NormalizeString((int)normalizationForm, strInput, strInput.Length, cBuffer, cBuffer.Length);
lastError = Marshal.GetLastWin32Error();
_hasInvariantNumberSigns = _positiveSign == "+" && _negativeSign == "-";
}
- internal NumberFormatInfo(CultureData cultureData)
+ internal NumberFormatInfo(CultureData? cultureData)
{
if (cultureData != null)
{
return PersianEra;
}
- public override int[]? Eras => new int[] { PersianEra };
+ public override int[] Eras => new int[] { PersianEra };
public override int GetMonth(DateTime time)
{
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
namespace System.Globalization
public class RegionInfo
{
// Name of this region (ie: es-US): serialized, the field used for deserialization
- private string _name;
+ private string _name = null!;
// The CultureData instance that we are going to read data from.
private readonly CultureData _cultureData;
// The RegionInfo for our current region
- internal static volatile RegionInfo s_currentRegionInfo;
+ internal static volatile RegionInfo? s_currentRegionInfo;
public RegionInfo(string name)
{
}
// For CoreCLR we only want the region names that are full culture names
- _cultureData = CultureData.GetCultureDataForRegion(name, true);
- if (_cultureData == null)
- {
+ _cultureData = CultureData.GetCultureDataForRegion(name, true) ??
throw new ArgumentException(SR.Format(SR.Argument_InvalidCultureName, name), nameof(name));
- }
// Not supposed to be neutral
if (_cultureData.IsNeutralCulture)
{
get
{
- RegionInfo temp = s_currentRegionInfo;
+ RegionInfo? temp = s_currentRegionInfo;
if (temp == null)
{
temp = new RegionInfo(CultureInfo.CurrentCulture._cultureData);
/// RegionInfos are considered equal if and only if they have the same name
/// (ie: en-US)
/// </summary>
- public override bool Equals(object value)
+ public override bool Equals(object? value)
{
return value is RegionInfo otherRegion
&& Name.Equals(otherRegion.Name);
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Runtime.CompilerServices;
namespace System.Globalization
{
[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
- public sealed class SortVersion : IEquatable<SortVersion>
+ public sealed class SortVersion : IEquatable<SortVersion?>
{
private int m_NlsVersion; // Do not rename (binary serialization)
private Guid m_SortId; // Do not rename (binary serialization)
m_SortId = customVersion;
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
return obj is SortVersion otherVersion && Equals(otherVersion);
}
- public bool Equals(SortVersion other)
+ public bool Equals(SortVersion? other)
{
if (other == null)
{
// Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool operator ==(SortVersion left, SortVersion right)
+ public static bool operator ==(SortVersion? left, SortVersion? right)
{
// Test "right" first to allow branch elimination when inlined for null checks (== null)
// so it can become a simple test
return right.Equals(left);
}
- public static bool operator !=(SortVersion left, SortVersion right)
+ public static bool operator !=(SortVersion? left, SortVersion? right)
{
return !(left == right);
}
/// </summary>
public class StringInfo
{
- private string _str;
+ private string _str = null!;
private int[]? _indexes;
public StringInfo(string value)
{
- _str = null!;
this.String = value;
}
// So yearOffset = 1911
private static EraInfo[] s_taiwanEraInfo = new EraInfo[]
{
- new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear
+ new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear
};
private static volatile Calendar s_defaultInstance;
return _helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era);
}
- public override int[]? Eras => _helper.Eras;
+ public override int[] Eras => _helper.Eras;
private const int DefaultTwoDigitYearMax = 99;
// So yearOffset = 1911
private static readonly EraInfo[] s_taiwanLunisolarEraInfo = new EraInfo[]
{
- new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear
+ new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear
};
private readonly GregorianCalendarHelper _helper;
internal override CalendarId ID => CalendarId.TAIWANLUNISOLAR;
- public override int[]? Eras => _helper.Eras;
+ public override int[] Eras => _helper.Eras;
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
namespace System.Globalization
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
True = 2
}
- private string _listSeparator;
+ private string? _listSeparator;
private bool _isReadOnly = false;
private readonly string _cultureName;
get => s_invariant ?? (s_invariant = new TextInfo(CultureData.Invariant));
}
- private volatile static TextInfo s_invariant;
+ private volatile static TextInfo? s_invariant;
internal TextInfo(CultureData cultureData)
{
/// </summary>
public bool IsRightToLeft => _cultureData.IsRightToLeft;
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
return obj is TextInfo otherTextInfo
&& CultureName.Equals(otherTextInfo.CultureName);
}
StringBuilder result = new StringBuilder();
- string lowercaseData = null;
+ string? lowercaseData = null;
// Store if the current culture is Dutch (special case)
bool isDutchCulture = CultureName.StartsWith("nl-", StringComparison.OrdinalIgnoreCase);
return _helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era);
}
- public override int[]? Eras => _helper.Eras;
+ public override int[] Eras => _helper.Eras;
private const int DefaultTwoDigitYearMax = 2572;
return UmAlQuraEra;
}
- public override int[]? Eras => new int[] { UmAlQuraEra };
+ public override int[] Eras => new int[] { UmAlQuraEra };
public override int GetMonth(DateTime time)
{