[System.Security.SecurityCritical] // auto-generated
internal TokenHashValue[] CreateTokenHashTable() {
TokenHashValue[] temp = m_dtfiTokenHash;
if (temp == null) {
temp = new TokenHashValue[TOKEN_HASH_SIZE];
bool koreanLanguage = LanguageName.Equals(KoreanLangName);
string sep = this.TimeSeparator.Trim();
if (IgnorableComma != sep) InsertHash(temp, IgnorableComma, TokenType.IgnorableSymbol, 0);
if (IgnorablePeriod != sep) InsertHash(temp, IgnorablePeriod, TokenType.IgnorableSymbol, 0);
if (KoreanHourSuff != sep && CJKHourSuff != sep && ChineseHourSuff != sep) {
//
// On the Macintosh, the default TimeSeparator is identical to the KoreanHourSuff, CJKHourSuff, or ChineseHourSuff for some cultures like
// ja-JP and ko-KR. In these cases having the same symbol inserted into the hash table with multiple TokenTypes causes undesirable
// DateTime.Parse behavior. For instance, the DateTimeFormatInfo.Tokenize() method might return SEP_DateOrOffset for KoreanHourSuff
// instead of SEP_HourSuff.
//
InsertHash(temp, this.TimeSeparator, TokenType.SEP_Time, 0);
}
InsertHash(temp, this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
InsertHash(temp, this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
//
if (LanguageName.Equals("sq")) {
// Albanian allows time formats like "12:00.PD"
InsertHash(temp, IgnorablePeriod + this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
InsertHash(temp, IgnorablePeriod + this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
}
// CJK suffix
InsertHash(temp, CJKYearSuff, TokenType.SEP_YearSuff, 0);
InsertHash(temp, KoreanYearSuff, TokenType.SEP_YearSuff, 0);
InsertHash(temp, CJKMonthSuff, TokenType.SEP_MonthSuff, 0);
InsertHash(temp, KoreanMonthSuff, TokenType.SEP_MonthSuff, 0);
InsertHash(temp, CJKDaySuff, TokenType.SEP_DaySuff, 0);
InsertHash(temp, KoreanDaySuff, TokenType.SEP_DaySuff, 0);
InsertHash(temp, CJKHourSuff, TokenType.SEP_HourSuff, 0);
InsertHash(temp, ChineseHourSuff, TokenType.SEP_HourSuff, 0);
InsertHash(temp, CJKMinuteSuff, TokenType.SEP_MinuteSuff, 0);
InsertHash(temp, CJKSecondSuff, TokenType.SEP_SecondSuff, 0);
//
if (koreanLanguage) {
// Korean suffix
InsertHash(temp, KoreanHourSuff, TokenType.SEP_HourSuff, 0);
InsertHash(temp, KoreanMinuteSuff, TokenType.SEP_MinuteSuff, 0);
InsertHash(temp, KoreanSecondSuff, TokenType.SEP_SecondSuff, 0);
}
if ( LanguageName.Equals("ky")) {
// For some cultures, the date separator works more like a comma, being allowed before or after any date part
InsertHash(temp, dateSeparatorOrTimeZoneOffset, TokenType.IgnorableSymbol, 0);
}
else {
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();
// Enumarate all LongDatePatterns, and get the DateWords and scan for month postfix.
// The only reason they're being assigned to m_dateWords is for Whidbey Deserialization
m_dateWords = dateWords = scanner.GetDateWordsOfDTFI(this);
// Ensure the formatflags is initialized.
DateTimeFormatFlags flag = FormatFlags;
// For some cultures, the date separator works more like a comma, being allowed before or after any date part.
// In these cultures, we do not use normal date separator since we disallow date separator after a date terminal state.
// This is determined in DateTimeFormatInfoScanner. Use this flag to determine if we should treat date separator as ignorable symbol.
bool useDateSepAsIgnorableSymbol = false;
String monthPostfix = null;
if (dateWords != null)
{
// There are DateWords. It could be a real date word (such as "de"), or a monthPostfix.
// The monthPostfix starts with '\xfffe' (MonthPostfixChar), followed by the real monthPostfix.
for (int i = 0; i < dateWords.Length; i++)
{
switch (dateWords[i][0])
{
// This is a month postfix
case DateTimeFormatInfoScanner.MonthPostfixChar:
// Get the real month postfix.
monthPostfix = dateWords[i].Substring(1);
// Add the month name + postfix into the token.
AddMonthNames(temp, monthPostfix);
break;
case DateTimeFormatInfoScanner.IgnorableSymbolChar:
String symbol = dateWords[i].Substring(1);
InsertHash(temp, symbol, TokenType.IgnorableSymbol, 0);
if (this.DateSeparator.Trim(null).Equals(symbol))
{
// The date separator is the same as the ingorable symbol.
useDateSepAsIgnorableSymbol = true;
}
break;
default:
InsertHash(temp, dateWords[i], TokenType.DateWordToken, 0);
//
if (LanguageName.Equals("eu")) {
// Basque has date words with leading dots
InsertHash(temp, IgnorablePeriod + dateWords[i], TokenType.DateWordToken, 0);
}
break;
}
}
}
if (!useDateSepAsIgnorableSymbol)
{
// Use the normal date separator.
InsertHash(temp, this.DateSeparator, TokenType.SEP_Date, 0);
}
// Add the regular month names.
AddMonthNames(temp, null);
// Add the abbreviated month names.
for (int i = 1; i <= 13; i++) {
InsertHash(temp, GetAbbreviatedMonthName(i), TokenType.MonthToken, i);
}
if ((FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0) {
for (int i = 1; i <= 13; i++) {
String str;
str = internalGetMonthName(i, MonthNameStyles.Genitive, false);
InsertHash(temp, str, TokenType.MonthToken, i);
}
}
if ((FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0) {
for (int i = 1; i <= 13; i++) {
String str;
str = internalGetMonthName(i, MonthNameStyles.LeapYear, false);
InsertHash(temp, str, TokenType.MonthToken, i);
}
}
for (int i = 0; i < 7; i++) {
//String str = GetDayOfWeekNames()[i];
// We have to call public methods here to work with inherited DTFI.
String str = GetDayName((DayOfWeek)i);
InsertHash(temp, str, TokenType.DayOfWeekToken, i);
str = GetAbbreviatedDayName((DayOfWeek)i);
InsertHash(temp, str, TokenType.DayOfWeekToken, i);
}
int[] eras = calendar.Eras;
for (int i = 1; i <= eras.Length; i++) {
InsertHash(temp, GetEraName(i), TokenType.EraToken, i);
InsertHash(temp, GetAbbreviatedEraName(i), TokenType.EraToken, i);
}
//
if (LanguageName.Equals(JapaneseLangName)) {
// Japanese allows day of week forms like: "(Tue)"
for (int i = 0; i < 7; i++) {
String specialDayOfWeek = "(" + GetAbbreviatedDayName((DayOfWeek)i) + ")";
InsertHash(temp, specialDayOfWeek, TokenType.DayOfWeekToken, i);
}
if (this.Calendar.GetType() != typeof(JapaneseCalendar)) {
// Special case for Japanese. If this is a Japanese DTFI, and the calendar is not Japanese calendar,
// we will check Japanese Era name as well when the calendar is Gregorian.
DateTimeFormatInfo jaDtfi = GetJapaneseCalendarDTFI();
for (int i = 1; i <= jaDtfi.Calendar.Eras.Length; i++) {
InsertHash(temp, jaDtfi.GetEraName(i), TokenType.JapaneseEraToken, i);
InsertHash(temp, jaDtfi.GetAbbreviatedEraName(i), TokenType.JapaneseEraToken, i);
// m_abbrevEnglishEraNames[0] contains the name for era 1, so the token value is i+1.
InsertHash(temp, jaDtfi.AbbreviatedEnglishEraNames[i-1], TokenType.JapaneseEraToken, i);
}
}
}
//
else if (CultureName.Equals("zh-TW")) {
DateTimeFormatInfo twDtfi = GetTaiwanCalendarDTFI();
for (int i = 1; i <= twDtfi.Calendar.Eras.Length; i++) {
if (twDtfi.GetEraName(i).Length > 0) {
InsertHash(temp, twDtfi.GetEraName(i), TokenType.TEraToken, i);
}
}
}
InsertHash(temp, InvariantInfo.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
InsertHash(temp, InvariantInfo.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
// Add invariant month names and day names.
for (int i = 1; i <= 12; i++) {
String str;
// We have to call public methods here to work with inherited DTFI.
// Insert the month name first, so that they are at the front of abbrevaited
// month names.
str = InvariantInfo.GetMonthName(i);
InsertHash(temp, str, TokenType.MonthToken, i);
str = InvariantInfo.GetAbbreviatedMonthName(i);
InsertHash(temp, str, TokenType.MonthToken, i);
}
for (int i = 0; i < 7; i++) {
// We have to call public methods here to work with inherited DTFI.
String str = InvariantInfo.GetDayName((DayOfWeek)i);
InsertHash(temp, str, TokenType.DayOfWeekToken, i);
str = InvariantInfo.GetAbbreviatedDayName((DayOfWeek)i);
InsertHash(temp, str, TokenType.DayOfWeekToken, i);
}
for (int i = 0; i < AbbreviatedEnglishEraNames.Length; i++) {
// m_abbrevEnglishEraNames[0] contains the name for era 1, so the token value is i+1.
InsertHash(temp, AbbreviatedEnglishEraNames[i], TokenType.EraToken, i + 1);
}
InsertHash(temp, LocalTimeMark, TokenType.SEP_LocalTimeMark, 0);
InsertHash(temp, DateTimeParse.GMTName, TokenType.TimeZoneToken, 0);
InsertHash(temp, DateTimeParse.ZuluName, TokenType.TimeZoneToken, 0);
InsertHash(temp, invariantDateSeparator, TokenType.SEP_Date, 0);
InsertHash(temp, invariantTimeSeparator, TokenType.SEP_Time, 0);
m_dtfiTokenHash = temp;
}
return (temp);
}