[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);
        }
 private void AddMonthNames(TokenHashValue[] temp, String monthPostfix)
 {
     for (int i = 1; i <= 13; i++) {
         String str;
         //str = internalGetMonthName(i, MonthNameStyles.Regular, false);
         // 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 = GetMonthName(i);
         if (str.Length > 0) {
             if (monthPostfix != null) {
                 // Insert the month name with the postfix first, so it can be matched first.
                 InsertHash(temp, str + monthPostfix, TokenType.MonthToken, i);
             } else
             {
                 InsertHash(temp, str, TokenType.MonthToken, i);
             }
         }
         str = GetAbbreviatedMonthName(i);
         InsertHash(temp, str, TokenType.MonthToken, i);
     }
 
 }
 private void InsertHash(TokenHashValue[] hashTable, string str, TokenType tokenType, int tokenValue)
 {
     if (str == null || str.Length == 0)
     return;
       int pos = 0;
       if (char.IsWhiteSpace(str[0]) || char.IsWhiteSpace(str[str.Length - 1]))
       {
     str = str.Trim((char[]) null);
     if (str.Length == 0)
       return;
       }
       char ch = char.ToLower(str[0], this.Culture);
       int hashcode = (int) ch % 199;
       int hashProbe = 1 + (int) ch % 197;
       do
       {
     TokenHashValue tokenHashValue = hashTable[hashcode];
     if (tokenHashValue == null)
     {
       hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);
       break;
     }
     else
     {
       if (str.Length >= tokenHashValue.tokenString.Length && string.Compare(str, 0, tokenHashValue.tokenString, 0, tokenHashValue.tokenString.Length, this.Culture, CompareOptions.IgnoreCase) == 0)
       {
     if (str.Length > tokenHashValue.tokenString.Length)
     {
       this.InsertAtCurrentHashNode(hashTable, str, ch, tokenType, tokenValue, pos, hashcode, hashProbe);
       break;
     }
     else
     {
       int num1 = (int) tokenType;
       int num2 = (int) tokenHashValue.tokenType;
       if (((num1 | num2) & (int) byte.MaxValue) == num1 || ((num1 | num2) & 65280) == num1)
       {
         tokenHashValue.tokenType |= tokenType;
         if (tokenValue != 0)
           tokenHashValue.tokenValue = tokenValue;
       }
     }
       }
       ++pos;
       hashcode += hashProbe;
       if (hashcode >= 199)
     hashcode -= 199;
     }
       }
       while (pos < 199);
 }
Example #4
0
        private void InsertHash(TokenHashValue[] hashTable, String str, TokenType tokenType, int tokenValue)
        {
            // The month of the 13th month is allowed to be null, so make sure that we ignore null value here.
            if (str == null || str.Length == 0)
            {
                return;
            }
            TokenHashValue value;
            int i = 0;
            // If there is whitespace characters in the beginning and end of the string, trim them since whitespaces are skipped by
            // DateTime.Parse().
            if (Char.IsWhiteSpace(str[0]) || Char.IsWhiteSpace(str[str.Length - 1]))
            {
                str = str.Trim(null);   // Trim white space characters.
                // Could have space for separators
                if (str.Length == 0)
                    return;
            }
            char ch = this.Culture.TextInfo.ToLower(str[0]);
            int hashcode = ch % TOKEN_HASH_SIZE;
            int hashProbe = 1 + ch % SECOND_PRIME;
            do
            {
                value = hashTable[hashcode];
                if (value == null)
                {
                    //// Console.WriteLine("   Put Key: {0} in {1}", str, hashcode);
                    hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);
                    return;
                }
                else
                {
                    // Collision happens. Find another slot.
                    if (str.Length >= value.tokenString.Length)
                    {
                        // If there are two tokens with the same prefix, we have to make sure that the longer token should be at the front of
                        // the shorter ones.
                        if (this.Culture.CompareInfo.Compare(str, 0, value.tokenString.Length, value.tokenString, 0, value.tokenString.Length, CompareOptions.IgnoreCase) == 0)
                        {
                            if (str.Length > value.tokenString.Length)
                            {
                                // The str to be inserted has the same prefix as the current token, and str is longer.
                                // Insert str into this node, and shift every node behind it.
                                InsertAtCurrentHashNode(hashTable, str, ch, tokenType, tokenValue, i, hashcode, hashProbe);
                                return;
                            }
                            else
                            {
                                // Same token.  If they have different types (regular token vs separator token).  Add them.
                                // If we have the same regular token or separator token in the hash already, do NOT update the hash.
                                // Therefore, the order of inserting token is significant here regarding what tokenType will be kept in the hash.


                                //
                                // Check the current value of RegularToken (stored in the lower 8-bit of tokenType) , and insert the tokenType into the hash ONLY when we don't have a RegularToken yet.
                                // Also check the current value of SeparatorToken (stored in the upper 8-bit of token), and insert the tokenType into the hash ONLY when we don't have the SeparatorToken yet.
                                //

                                int nTokenType = (int)tokenType;
                                int nCurrentTokenTypeInHash = (int)value.tokenType;

                                //
                                // The folowing is the fix for the issue of throwing FormatException when "mar" is passed in string of the short date format dd/MMM/yyyy for es-MX
                                //

                                if (((nCurrentTokenTypeInHash & (int)TokenType.RegularTokenMask) == 0) && ((nTokenType & (int)TokenType.RegularTokenMask) != 0) ||
                                    ((nCurrentTokenTypeInHash & (int)TokenType.SeparatorTokenMask) == 0) && ((nTokenType & (int)TokenType.SeparatorTokenMask) != 0))
                                {
                                    value.tokenType |= tokenType;
                                    if (tokenValue != 0)
                                    {
                                        value.tokenValue = tokenValue;
                                    }
                                }
                                // The token to be inserted is already in the table.  Skip it.
                            }
                        }
                    }
                }
                //// Console.WriteLine("  COLLISION. Old Key: {0}, New Key: {1}", hashTable[hashcode].tokenString, str);
                i++;
                hashcode += hashProbe;
                if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
            } while (i < TOKEN_HASH_SIZE);
            Contract.Assert(true, "The hashtable is full.  This should not happen.");
        }
 private void AddMonthNames(TokenHashValue[] temp, string monthPostfix)
 {
     for (int index = 1; index <= 13; ++index)
       {
     string monthName = this.GetMonthName(index);
     if (monthName.Length > 0)
     {
       if (monthPostfix != null)
     this.InsertHash(temp, monthName + monthPostfix, TokenType.MonthToken, index);
       else
     this.InsertHash(temp, monthName, TokenType.MonthToken, index);
     }
     string abbreviatedMonthName = this.GetAbbreviatedMonthName(index);
     this.InsertHash(temp, abbreviatedMonthName, TokenType.MonthToken, index);
       }
 }
 private void InsertAtCurrentHashNode(TokenHashValue[] hashTable, string str, char ch, TokenType tokenType, int tokenValue, int pos, int hashcode, int hashProbe)
 {
     TokenHashValue tokenHashValue1 = hashTable[hashcode];
       hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);
       while (++pos < 199)
       {
     hashcode += hashProbe;
     if (hashcode >= 199)
       hashcode -= 199;
     TokenHashValue tokenHashValue2 = hashTable[hashcode];
     if (tokenHashValue2 == null || (int) char.ToLower(tokenHashValue2.tokenString[0], this.Culture) == (int) ch)
     {
       hashTable[hashcode] = tokenHashValue1;
       if (tokenHashValue2 == null)
     break;
       tokenHashValue1 = tokenHashValue2;
     }
       }
 }
 private void InsertHash(TokenHashValue[] hashTable, string str, TokenType tokenType, int tokenValue)
 {
     TokenHashValue value2;
     if ((str == null) || (str.Length == 0))
     {
         return;
     }
     int pos = 0;
     if (char.IsWhiteSpace(str[0]) || char.IsWhiteSpace(str[str.Length - 1]))
     {
         str = str.Trim(null);
         if (str.Length == 0)
         {
             return;
         }
     }
     char ch = char.ToLower(str[0], this.Culture);
     int index = ch % '\x00c7';
     int hashProbe = 1 + (ch % '\x00c5');
 Label_0069:
     value2 = hashTable[index];
     if (value2 == null)
     {
         hashTable[index] = new TokenHashValue(str, tokenType, tokenValue);
     }
     else
     {
         if ((str.Length >= value2.tokenString.Length) && (string.Compare(str, 0, value2.tokenString, 0, value2.tokenString.Length, this.Culture, CompareOptions.IgnoreCase) == 0))
         {
             if (str.Length > value2.tokenString.Length)
             {
                 this.InsertAtCurrentHashNode(hashTable, str, ch, tokenType, tokenValue, pos, index, hashProbe);
                 return;
             }
             int num4 = (int) tokenType;
             int num5 = (int) value2.tokenType;
             if ((((num4 | num5) & 0xff) == num4) || (((num4 | num5) & 0xff00) == num4))
             {
                 value2.tokenType |= tokenType;
                 if (tokenValue != 0)
                 {
                     value2.tokenValue = tokenValue;
                 }
             }
         }
         pos++;
         index += hashProbe;
         if (index >= 0xc7)
         {
             index -= 0xc7;
         }
         if (pos < 0xc7)
         {
             goto Label_0069;
         }
     }
 }
 void InsertHash(TokenHashValue[] hashTable, String str, TokenType tokenType, int tokenValue) {
     // The month of the 13th month is allowed to be null, so make sure that we ignore null value here.
     if (str == null || str.Length == 0) {
         return;
     }
     TokenHashValue value;
     int i = 0;
     // If there is whitespace characters in the beginning and end of the string, trim them since whitespaces are skipped by
     // DateTime.Parse().
     if (Char.IsWhiteSpace(str[0]) || Char.IsWhiteSpace(str[str.Length - 1])) {
         str = str.Trim(null);   // Trim white space characters.
     }
     char ch = Char.ToLower(str[0], CultureInfo.CurrentCulture);
     int hashcode = ch % TOKEN_HASH_SIZE;
     int hashProbe = 1 + ch % SECOND_PRIME;
     do {
         value = hashTable[hashcode];
         if (value == null) {
             //// Console.WriteLine("   Put Key: {0} in {1}", str, hashcode);
             hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);
             return;
         } else {
             // Collision happens. Find another slot.
             if (str.Length >= value.tokenString.Length) {
                 // If there are two tokens with the same prefix, we have to make sure that the longer token should be at the front of
                 // the shorter ones.
                 if (String.Compare(str, 0, value.tokenString, 0, value.tokenString.Length, true, CultureInfo.CurrentCulture) == 0) {
                     if (str.Length > value.tokenString.Length) {
                         // The str to be inserted has the same prefix as the current token, and str is longer.
                         // Insert str into this node, and shift every node behind it.
                         InsertAtCurrentHashNode(hashTable, str, ch, tokenType, tokenValue, i, hashcode, hashProbe);
                         return;
                     } else {
                         // Same token.  If they have different types (regular token vs separator token.  Add them.
                         if (((int)tokenType & 0xff00) != ((int)value.tokenType & 0xff00)) {
                             value.tokenType |= tokenType;
                             if (tokenValue != 0) {
                                 value.tokenValue = tokenValue;
                             }
                         }
                         // The token to be inserted is already in the table.  Skip it.
                     }
                 }
             }
         }
         //// Console.WriteLine("  COLLISION. Old Key: {0}, New Key: {1}", hashTable[hashcode].tokenString, str);
         i++;
         hashcode += hashProbe;
         if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
     } while (i < TOKEN_HASH_SIZE);
     BCLDebug.Assert(true, "The hashtable is full.  This should not happen.");
 }
        internal TokenHashValue[] CreateTokenHashTable()
        {
            TokenHashValue[] dtfiTokenHash = this.m_dtfiTokenHash;
            if (dtfiTokenHash == null)
            {
                dtfiTokenHash = new TokenHashValue[0xc7];
                bool flag = this.LanguageName.Equals("ko");
                string str = this.TimeSeparator.Trim();
                if ("," != str)
                {
                    this.InsertHash(dtfiTokenHash, ",", TokenType.IgnorableSymbol, 0);
                }
                if ("." != str)
                {
                    this.InsertHash(dtfiTokenHash, ".", TokenType.IgnorableSymbol, 0);
                }
                if ((("시" != str) && ("時" != str)) && ("时" != str))
                {
                    this.InsertHash(dtfiTokenHash, this.TimeSeparator, TokenType.SEP_Time, 0);
                }
                this.InsertHash(dtfiTokenHash, this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
                this.InsertHash(dtfiTokenHash, this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
                if (this.LanguageName.Equals("sq"))
                {
                    this.InsertHash(dtfiTokenHash, "." + this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
                    this.InsertHash(dtfiTokenHash, "." + this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
                }
                this.InsertHash(dtfiTokenHash, "年", TokenType.SEP_YearSuff, 0);
                this.InsertHash(dtfiTokenHash, "년", TokenType.SEP_YearSuff, 0);
                this.InsertHash(dtfiTokenHash, "月", TokenType.SEP_MonthSuff, 0);
                this.InsertHash(dtfiTokenHash, "월", TokenType.SEP_MonthSuff, 0);
                this.InsertHash(dtfiTokenHash, "日", TokenType.SEP_DaySuff, 0);
                this.InsertHash(dtfiTokenHash, "일", TokenType.SEP_DaySuff, 0);
                this.InsertHash(dtfiTokenHash, "時", TokenType.SEP_HourSuff, 0);
                this.InsertHash(dtfiTokenHash, "时", TokenType.SEP_HourSuff, 0);
                this.InsertHash(dtfiTokenHash, "分", TokenType.SEP_MinuteSuff, 0);
                this.InsertHash(dtfiTokenHash, "秒", TokenType.SEP_SecondSuff, 0);
                if (flag)
                {
                    this.InsertHash(dtfiTokenHash, "시", TokenType.SEP_HourSuff, 0);
                    this.InsertHash(dtfiTokenHash, "분", TokenType.SEP_MinuteSuff, 0);
                    this.InsertHash(dtfiTokenHash, "초", TokenType.SEP_SecondSuff, 0);
                }
                if (this.LanguageName.Equals("ky"))
                {
                    this.InsertHash(dtfiTokenHash, "-", TokenType.IgnorableSymbol, 0);
                }
                else
                {
                    this.InsertHash(dtfiTokenHash, "-", TokenType.SEP_DateOrOffset, 0);
                }
                string[] strArray = null;
                DateTimeFormatInfoScanner scanner = null;
                scanner = new DateTimeFormatInfoScanner();
                this.m_dateWords = strArray = scanner.GetDateWordsOfDTFI(this);
                DateTimeFormatFlags formatFlags = this.FormatFlags;
                bool flag2 = false;
                string monthPostfix = null;
                if (strArray != null)
                {
                    for (int num = 0; num < strArray.Length; num++)
                    {
                        switch (strArray[num][0])
                        {
                            case 0xe000:
                                monthPostfix = strArray[num].Substring(1);
                                this.AddMonthNames(dtfiTokenHash, monthPostfix);
                                break;

                            case 0xe001:
                            {
                                string str3 = strArray[num].Substring(1);
                                this.InsertHash(dtfiTokenHash, str3, TokenType.IgnorableSymbol, 0);
                                if (this.DateSeparator.Trim(null).Equals(str3))
                                {
                                    flag2 = true;
                                }
                                break;
                            }
                            default:
                                this.InsertHash(dtfiTokenHash, strArray[num], TokenType.DateWordToken, 0);
                                if (this.LanguageName.Equals("eu"))
                                {
                                    this.InsertHash(dtfiTokenHash, "." + strArray[num], TokenType.DateWordToken, 0);
                                }
                                break;
                        }
                    }
                }
                if (!flag2)
                {
                    this.InsertHash(dtfiTokenHash, this.DateSeparator, TokenType.SEP_Date, 0);
                }
                this.AddMonthNames(dtfiTokenHash, null);
                for (int i = 1; i <= 13; i++)
                {
                    this.InsertHash(dtfiTokenHash, this.GetAbbreviatedMonthName(i), TokenType.MonthToken, i);
                }
                if ((this.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != DateTimeFormatFlags.None)
                {
                    for (int num3 = 1; num3 <= 13; num3++)
                    {
                        string str4 = this.internalGetMonthName(num3, MonthNameStyles.Genitive, false);
                        this.InsertHash(dtfiTokenHash, str4, TokenType.MonthToken, num3);
                    }
                }
                if ((this.FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != DateTimeFormatFlags.None)
                {
                    for (int num4 = 1; num4 <= 13; num4++)
                    {
                        string str5 = this.internalGetMonthName(num4, MonthNameStyles.LeapYear, false);
                        this.InsertHash(dtfiTokenHash, str5, TokenType.MonthToken, num4);
                    }
                }
                for (int j = 0; j < 7; j++)
                {
                    string dayName = this.GetDayName((DayOfWeek) j);
                    this.InsertHash(dtfiTokenHash, dayName, TokenType.DayOfWeekToken, j);
                    dayName = this.GetAbbreviatedDayName((DayOfWeek) j);
                    this.InsertHash(dtfiTokenHash, dayName, TokenType.DayOfWeekToken, j);
                }
                int[] eras = this.calendar.Eras;
                for (int k = 1; k <= eras.Length; k++)
                {
                    this.InsertHash(dtfiTokenHash, this.GetEraName(k), TokenType.EraToken, k);
                    this.InsertHash(dtfiTokenHash, this.GetAbbreviatedEraName(k), TokenType.EraToken, k);
                }
                if (this.LanguageName.Equals("ja"))
                {
                    for (int num7 = 0; num7 < 7; num7++)
                    {
                        string str7 = "(" + this.GetAbbreviatedDayName((DayOfWeek) num7) + ")";
                        this.InsertHash(dtfiTokenHash, str7, TokenType.DayOfWeekToken, num7);
                    }
                    if (this.Calendar.GetType() != typeof(JapaneseCalendar))
                    {
                        DateTimeFormatInfo japaneseCalendarDTFI = GetJapaneseCalendarDTFI();
                        for (int num8 = 1; num8 <= japaneseCalendarDTFI.Calendar.Eras.Length; num8++)
                        {
                            this.InsertHash(dtfiTokenHash, japaneseCalendarDTFI.GetEraName(num8), TokenType.JapaneseEraToken, num8);
                            this.InsertHash(dtfiTokenHash, japaneseCalendarDTFI.GetAbbreviatedEraName(num8), TokenType.JapaneseEraToken, num8);
                            this.InsertHash(dtfiTokenHash, japaneseCalendarDTFI.AbbreviatedEnglishEraNames[num8 - 1], TokenType.JapaneseEraToken, num8);
                        }
                    }
                }
                else if (this.CultureName.Equals("zh-TW"))
                {
                    DateTimeFormatInfo taiwanCalendarDTFI = GetTaiwanCalendarDTFI();
                    for (int num9 = 1; num9 <= taiwanCalendarDTFI.Calendar.Eras.Length; num9++)
                    {
                        if (taiwanCalendarDTFI.GetEraName(num9).Length > 0)
                        {
                            this.InsertHash(dtfiTokenHash, taiwanCalendarDTFI.GetEraName(num9), TokenType.TEraToken, num9);
                        }
                    }
                }
                this.InsertHash(dtfiTokenHash, InvariantInfo.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
                this.InsertHash(dtfiTokenHash, InvariantInfo.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
                for (int m = 1; m <= 12; m++)
                {
                    string monthName = InvariantInfo.GetMonthName(m);
                    this.InsertHash(dtfiTokenHash, monthName, TokenType.MonthToken, m);
                    monthName = InvariantInfo.GetAbbreviatedMonthName(m);
                    this.InsertHash(dtfiTokenHash, monthName, TokenType.MonthToken, m);
                }
                for (int n = 0; n < 7; n++)
                {
                    string abbreviatedDayName = InvariantInfo.GetDayName((DayOfWeek) n);
                    this.InsertHash(dtfiTokenHash, abbreviatedDayName, TokenType.DayOfWeekToken, n);
                    abbreviatedDayName = InvariantInfo.GetAbbreviatedDayName((DayOfWeek) n);
                    this.InsertHash(dtfiTokenHash, abbreviatedDayName, TokenType.DayOfWeekToken, n);
                }
                for (int num12 = 0; num12 < this.AbbreviatedEnglishEraNames.Length; num12++)
                {
                    this.InsertHash(dtfiTokenHash, this.AbbreviatedEnglishEraNames[num12], TokenType.EraToken, num12 + 1);
                }
                this.InsertHash(dtfiTokenHash, "T", TokenType.SEP_LocalTimeMark, 0);
                this.InsertHash(dtfiTokenHash, "GMT", TokenType.TimeZoneToken, 0);
                this.InsertHash(dtfiTokenHash, "Z", TokenType.TimeZoneToken, 0);
                this.InsertHash(dtfiTokenHash, "/", TokenType.SEP_Date, 0);
                this.InsertHash(dtfiTokenHash, ":", TokenType.SEP_Time, 0);
                this.m_dtfiTokenHash = dtfiTokenHash;
            }
            return dtfiTokenHash;
        }
 private void InsertAtCurrentHashNode(TokenHashValue[] hashTable, string str, char ch, TokenType tokenType, int tokenValue, int pos, int hashcode, int hashProbe)
 {
     TokenHashValue value2 = hashTable[hashcode];
     hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);
     while (++pos < 0xc7)
     {
         hashcode += hashProbe;
         if (hashcode >= 0xc7)
         {
             hashcode -= 0xc7;
         }
         TokenHashValue value3 = hashTable[hashcode];
         if ((value3 == null) || (char.ToLower(value3.tokenString[0], this.Culture) == ch))
         {
             hashTable[hashcode] = value2;
             if (value3 == null)
             {
                 return;
             }
             value2 = value3;
         }
     }
 }
 private void AddMonthNames(TokenHashValue[] temp, string monthPostfix)
 {
     for (int i = 1; i <= 13; i++)
     {
         string monthName = this.GetMonthName(i);
         if (monthName.Length > 0)
         {
             if (monthPostfix != null)
             {
                 this.InsertHash(temp, monthName + monthPostfix, TokenType.MonthToken, i);
             }
             else
             {
                 this.InsertHash(temp, monthName, TokenType.MonthToken, i);
             }
         }
         monthName = this.GetAbbreviatedMonthName(i);
         this.InsertHash(temp, monthName, TokenType.MonthToken, i);
     }
 }
Example #12
0
 private void InsertHash(TokenHashValue[] hashTable, string str, TokenType tokenType, int tokenValue)
 {
     TokenHashValue value2;
     if ((str == null) || (str.Length == 0))
     {
         return;
     }
     int pos = 0;
     if (char.IsWhiteSpace(str[0]) || char.IsWhiteSpace(str[str.Length - 1]))
     {
         str = str.Trim(null);
         if (str.Length == 0)
         {
             return;
         }
     }
     char ch = char.ToLower(str[0], CultureInfo.CurrentCulture);
     int index = ch % '\x00c7';
     int hashProbe = 1 + (ch % '\x00c5');
 Label_0068:
     value2 = hashTable[index];
     if (value2 == null)
     {
         hashTable[index] = new TokenHashValue(str, tokenType, tokenValue);
     }
     else
     {
         if ((str.Length >= value2.tokenString.Length) && (string.Compare(str, 0, value2.tokenString, 0, value2.tokenString.Length, true, CultureInfo.CurrentCulture) == 0))
         {
             if (str.Length > value2.tokenString.Length)
             {
                 this.InsertAtCurrentHashNode(hashTable, str, ch, tokenType, tokenValue, pos, index, hashProbe);
                 return;
             }
             if ((tokenType & TokenType.SeparatorTokenMask) != (value2.tokenType & TokenType.SeparatorTokenMask))
             {
                 value2.tokenType |= tokenType;
                 if (tokenValue != 0)
                 {
                     value2.tokenValue = tokenValue;
                 }
             }
         }
         pos++;
         index += hashProbe;
         if (index >= 0xc7)
         {
             index -= 0xc7;
         }
         if (pos < 0xc7)
         {
             goto Label_0068;
         }
     }
 }
Example #13
0
        void InsertHash(TokenHashValue[] hashTable, String str, TokenType tokenType, int tokenValue) {
            // The month of the 13th month is allowed to be null, so make sure that we ignore null value here. 
            if (str == null || str.Length == 0) { 
                return;
            } 
            TokenHashValue value;
            int i = 0;
            // If there is whitespace characters in the beginning and end of the string, trim them since whitespaces are skipped by
            // DateTime.Parse(). 
            if (Char.IsWhiteSpace(str[0]) || Char.IsWhiteSpace(str[str.Length - 1])) {
                str = str.Trim(null);   // Trim white space characters. 
                // Could have space for separators 
                if (str.Length == 0)
                    return; 
                }
            char ch = Char.ToLower(str[0], this.Culture);
            int hashcode = ch % TOKEN_HASH_SIZE;
            int hashProbe = 1 + ch % SECOND_PRIME; 
            do {
                value = hashTable[hashcode]; 
                if (value == null) { 
                    //// Console.WriteLine("   Put Key: {0} in {1}", str, hashcode);
                    hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue); 
                    return;
                } else {
                    // Collision happens. Find another slot.
                    if (str.Length >= value.tokenString.Length) { 
                        // If there are two tokens with the same prefix, we have to make sure that the longer token should be at the front of
                        // the shorter ones. 
                        if (String.Compare(str, 0, value.tokenString, 0, value.tokenString.Length, this.Culture, CompareOptions.IgnoreCase) == 0) { 
                            if (str.Length > value.tokenString.Length) {
                                // The str to be inserted has the same prefix as the current token, and str is longer. 
                                // Insert str into this node, and shift every node behind it.
                                InsertAtCurrentHashNode(hashTable, str, ch, tokenType, tokenValue, i, hashcode, hashProbe);
                                return;
                            } else { 
                                // Same token.  If they have different types (regular token vs separator token).  Add them.
                                // If we have the same regular token or separator token in the hash already, do NOT update the hash. 
                                // Therefore, the order of inserting token is significant here regarding what tokenType will be kept in the hash. 

 
                                //
                                // Check the current value of RegularToken (stored in the lower 8-bit of tokenType) , and insert the tokenType into the hash ONLY when we don't have a RegularToken yet.
                                // Also check the current value of SeparatorToken (stored in the upper 8-bit of token), and insert the tokenType into the hash ONLY when we don't have the SeparatorToken yet.
                                // 

                                int nTokenType = (int)tokenType; 
                                int nCurrentTokenTypeInHash = (int)value.tokenType; 

                                // 
                                // Since RegularToken are stored in the lower 8-bit, we use RegularTokenMask to mask the upper 8-bit.
                                // And SeparaToken are stroed in the upper 8-bit, we use SeparatorTokenMask to mask the lower 8-bit.
                                // We only pass either a RegularToken or a SeparatorToken to be inserted to this function, so only one of the statement below could be true after the masking.
                                // We do LOGICAL OR of the tokenType that we want to insert with the current tokenType in the hash (could be 0 or an existing non-zero value). 
                                // And we check the result after the OR with the tokenType that we want to insert. When the result is equal, it means that:
                                //      * Either the current tokenType is 0. 
                                //       * Or the tokenType to insert is the same as the one that is already in the hash. 
                                // If the alues are not the same, we will NOT update the table. This means that we will just keep the tokenType that we had before.
                                // 
                                if ((((nTokenType | nCurrentTokenTypeInHash) & (int)TokenType.RegularTokenMask) == nTokenType) ||
                                   (((nTokenType | nCurrentTokenTypeInHash) & (int)TokenType.SeparatorTokenMask) == nTokenType)) {
                                    value.tokenType |= tokenType;
                                    if (tokenValue != 0) { 
                                        value.tokenValue = tokenValue;
                                    } 
                                } 
                                // The token to be inserted is already in the table.  Skip it.
                            } 
                        }
                    }
                }
                //// Console.WriteLine("  COLLISION. Old Key: {0}, New Key: {1}", hashTable[hashcode].tokenString, str); 
                i++;
                hashcode += hashProbe; 
                if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE; 
            } while (i < TOKEN_HASH_SIZE);
            Contract.Assert(true, "The hashtable is full.  This should not happen."); 
        }
        void InsertAtCurrentHashNode(TokenHashValue[] hashTable, String str, char ch, TokenType tokenType, int tokenValue, int pos, int hashcode, int hashProbe) {
            // Remember the current slot.
            TokenHashValue previousNode = hashTable[hashcode];

            //// Console.WriteLine("   Insert Key: {0} in {1}", str, slotToInsert);
            // Insert the new node into the current slot.
            hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);;

            while (++pos < TOKEN_HASH_SIZE) {
                hashcode += hashProbe;
                if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
                // Remember this slot
                TokenHashValue temp = hashTable[hashcode];

                if (temp != null && Char.ToLower(temp.tokenString[0], this.Culture) != ch) {
                    continue;
                }
                // Put the previous slot into this slot.
                hashTable[hashcode] = previousNode;
                //// Console.WriteLine("  Move {0} to slot {1}", previousNode.tokenString, hashcode);
                if (temp == null) {
                    // Done
                    return;
                }
                previousNode = temp;
            } ;
            Contract.Assert(true, "The hashtable is full.  This should not happen.");
        }
 internal TokenHashValue[] CreateTokenHashTable()
 {
     TokenHashValue[] tokenHashValueArray = this.m_dtfiTokenHash;
       if (tokenHashValueArray == null)
       {
     tokenHashValueArray = new TokenHashValue[199];
     bool flag1 = this.LanguageName.Equals("ko");
     string str1 = this.TimeSeparator.Trim();
     if ("," != str1)
       this.InsertHash(tokenHashValueArray, ",", TokenType.IgnorableSymbol, 0);
     if ("." != str1)
       this.InsertHash(tokenHashValueArray, ".", TokenType.IgnorableSymbol, 0);
     if ("시" != str1 && "時" != str1 && "时" != str1)
       this.InsertHash(tokenHashValueArray, this.TimeSeparator, TokenType.SEP_Time, 0);
     this.InsertHash(tokenHashValueArray, this.AMDesignator, (TokenType) 1027, 0);
     this.InsertHash(tokenHashValueArray, this.PMDesignator, (TokenType) 1284, 1);
     if (this.LanguageName.Equals("sq"))
     {
       this.InsertHash(tokenHashValueArray, "." + this.AMDesignator, (TokenType) 1027, 0);
       this.InsertHash(tokenHashValueArray, "." + this.PMDesignator, (TokenType) 1284, 1);
     }
     this.InsertHash(tokenHashValueArray, "年", TokenType.SEP_YearSuff, 0);
     this.InsertHash(tokenHashValueArray, "년", TokenType.SEP_YearSuff, 0);
     this.InsertHash(tokenHashValueArray, "月", TokenType.SEP_MonthSuff, 0);
     this.InsertHash(tokenHashValueArray, "월", TokenType.SEP_MonthSuff, 0);
     this.InsertHash(tokenHashValueArray, "日", TokenType.SEP_DaySuff, 0);
     this.InsertHash(tokenHashValueArray, "일", TokenType.SEP_DaySuff, 0);
     this.InsertHash(tokenHashValueArray, "時", TokenType.SEP_HourSuff, 0);
     this.InsertHash(tokenHashValueArray, "时", TokenType.SEP_HourSuff, 0);
     this.InsertHash(tokenHashValueArray, "分", TokenType.SEP_MinuteSuff, 0);
     this.InsertHash(tokenHashValueArray, "秒", TokenType.SEP_SecondSuff, 0);
     if (flag1)
     {
       this.InsertHash(tokenHashValueArray, "시", TokenType.SEP_HourSuff, 0);
       this.InsertHash(tokenHashValueArray, "분", TokenType.SEP_MinuteSuff, 0);
       this.InsertHash(tokenHashValueArray, "초", TokenType.SEP_SecondSuff, 0);
     }
     if (this.LanguageName.Equals("ky"))
       this.InsertHash(tokenHashValueArray, "-", TokenType.IgnorableSymbol, 0);
     else
       this.InsertHash(tokenHashValueArray, "-", TokenType.SEP_DateOrOffset, 0);
     DateTimeFormatInfoScanner formatInfoScanner = new DateTimeFormatInfoScanner();
     string[] dateWordsOfDtfi;
     this.m_dateWords = dateWordsOfDtfi = formatInfoScanner.GetDateWordsOfDTFI(this);
     int num = (int) this.FormatFlags;
     bool flag2 = false;
     if (dateWordsOfDtfi != null)
     {
       for (int index = 0; index < dateWordsOfDtfi.Length; ++index)
       {
     switch (dateWordsOfDtfi[index][0])
     {
       case '\xE000':
         string monthPostfix = dateWordsOfDtfi[index].Substring(1);
         this.AddMonthNames(tokenHashValueArray, monthPostfix);
         break;
       case '\xE001':
         string str2 = dateWordsOfDtfi[index].Substring(1);
         this.InsertHash(tokenHashValueArray, str2, TokenType.IgnorableSymbol, 0);
         if (this.DateSeparator.Trim((char[]) null).Equals(str2))
         {
           flag2 = true;
           break;
         }
         else
           break;
       default:
         this.InsertHash(tokenHashValueArray, dateWordsOfDtfi[index], TokenType.DateWordToken, 0);
         if (this.LanguageName.Equals("eu"))
         {
           this.InsertHash(tokenHashValueArray, "." + dateWordsOfDtfi[index], TokenType.DateWordToken, 0);
           break;
         }
         else
           break;
     }
       }
     }
     if (!flag2)
       this.InsertHash(tokenHashValueArray, this.DateSeparator, TokenType.SEP_Date, 0);
     this.AddMonthNames(tokenHashValueArray, (string) null);
     for (int index = 1; index <= 13; ++index)
       this.InsertHash(tokenHashValueArray, this.GetAbbreviatedMonthName(index), TokenType.MonthToken, index);
     if ((this.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != DateTimeFormatFlags.None)
     {
       for (int index = 1; index <= 13; ++index)
       {
     string monthName = this.internalGetMonthName(index, MonthNameStyles.Genitive, false);
     this.InsertHash(tokenHashValueArray, monthName, TokenType.MonthToken, index);
       }
     }
     if ((this.FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != DateTimeFormatFlags.None)
     {
       for (int index = 1; index <= 13; ++index)
       {
     string monthName = this.internalGetMonthName(index, MonthNameStyles.LeapYear, false);
     this.InsertHash(tokenHashValueArray, monthName, TokenType.MonthToken, index);
       }
     }
     for (int tokenValue = 0; tokenValue < 7; ++tokenValue)
     {
       string dayName = this.GetDayName((DayOfWeek) tokenValue);
       this.InsertHash(tokenHashValueArray, dayName, TokenType.DayOfWeekToken, tokenValue);
       string abbreviatedDayName = this.GetAbbreviatedDayName((DayOfWeek) tokenValue);
       this.InsertHash(tokenHashValueArray, abbreviatedDayName, TokenType.DayOfWeekToken, tokenValue);
     }
     int[] eras = this.calendar.Eras;
     for (int index = 1; index <= eras.Length; ++index)
     {
       this.InsertHash(tokenHashValueArray, this.GetEraName(index), TokenType.EraToken, index);
       this.InsertHash(tokenHashValueArray, this.GetAbbreviatedEraName(index), TokenType.EraToken, index);
     }
     if (this.LanguageName.Equals("ja"))
     {
       for (int tokenValue = 0; tokenValue < 7; ++tokenValue)
       {
     string str2 = "(" + this.GetAbbreviatedDayName((DayOfWeek) tokenValue) + ")";
     this.InsertHash(tokenHashValueArray, str2, TokenType.DayOfWeekToken, tokenValue);
       }
       if (this.Calendar.GetType() != typeof (JapaneseCalendar))
       {
     DateTimeFormatInfo japaneseCalendarDtfi = DateTimeFormatInfo.GetJapaneseCalendarDTFI();
     for (int index = 1; index <= japaneseCalendarDtfi.Calendar.Eras.Length; ++index)
     {
       this.InsertHash(tokenHashValueArray, japaneseCalendarDtfi.GetEraName(index), TokenType.JapaneseEraToken, index);
       this.InsertHash(tokenHashValueArray, japaneseCalendarDtfi.GetAbbreviatedEraName(index), TokenType.JapaneseEraToken, index);
       this.InsertHash(tokenHashValueArray, japaneseCalendarDtfi.AbbreviatedEnglishEraNames[index - 1], TokenType.JapaneseEraToken, index);
     }
       }
     }
     else if (this.CultureName.Equals("zh-TW"))
     {
       DateTimeFormatInfo taiwanCalendarDtfi = DateTimeFormatInfo.GetTaiwanCalendarDTFI();
       for (int index = 1; index <= taiwanCalendarDtfi.Calendar.Eras.Length; ++index)
       {
     if (taiwanCalendarDtfi.GetEraName(index).Length > 0)
       this.InsertHash(tokenHashValueArray, taiwanCalendarDtfi.GetEraName(index), TokenType.TEraToken, index);
       }
     }
     this.InsertHash(tokenHashValueArray, DateTimeFormatInfo.InvariantInfo.AMDesignator, (TokenType) 1027, 0);
     this.InsertHash(tokenHashValueArray, DateTimeFormatInfo.InvariantInfo.PMDesignator, (TokenType) 1284, 1);
     for (int index = 1; index <= 12; ++index)
     {
       string monthName = DateTimeFormatInfo.InvariantInfo.GetMonthName(index);
       this.InsertHash(tokenHashValueArray, monthName, TokenType.MonthToken, index);
       string abbreviatedMonthName = DateTimeFormatInfo.InvariantInfo.GetAbbreviatedMonthName(index);
       this.InsertHash(tokenHashValueArray, abbreviatedMonthName, TokenType.MonthToken, index);
     }
     for (int tokenValue = 0; tokenValue < 7; ++tokenValue)
     {
       string dayName = DateTimeFormatInfo.InvariantInfo.GetDayName((DayOfWeek) tokenValue);
       this.InsertHash(tokenHashValueArray, dayName, TokenType.DayOfWeekToken, tokenValue);
       string abbreviatedDayName = DateTimeFormatInfo.InvariantInfo.GetAbbreviatedDayName((DayOfWeek) tokenValue);
       this.InsertHash(tokenHashValueArray, abbreviatedDayName, TokenType.DayOfWeekToken, tokenValue);
     }
     for (int index = 0; index < this.AbbreviatedEnglishEraNames.Length; ++index)
       this.InsertHash(tokenHashValueArray, this.AbbreviatedEnglishEraNames[index], TokenType.EraToken, index + 1);
     this.InsertHash(tokenHashValueArray, "T", TokenType.SEP_LocalTimeMark, 0);
     this.InsertHash(tokenHashValueArray, "GMT", TokenType.TimeZoneToken, 0);
     this.InsertHash(tokenHashValueArray, "Z", TokenType.TimeZoneToken, 0);
     this.InsertHash(tokenHashValueArray, "/", TokenType.SEP_Date, 0);
     this.InsertHash(tokenHashValueArray, ":", TokenType.SEP_Time, 0);
     this.m_dtfiTokenHash = tokenHashValueArray;
       }
       return tokenHashValueArray;
 }
        void InsertHash(TokenHashValue[] hashTable, String str, TokenType tokenType, int tokenValue) {
            // The month of the 13th month is allowed to be null, so make sure that we ignore null value here.
            if (str == null || str.Length == 0) {
                return;
            }
            TokenHashValue value;
            int i = 0;
            // If there is whitespace characters in the beginning and end of the string, trim them since whitespaces are skipped by
            // DateTime.Parse().
            if (Char.IsWhiteSpace(str[0]) || Char.IsWhiteSpace(str[str.Length - 1])) {
                str = str.Trim(null);   // Trim white space characters.
                // Could have space for separators
                if (str.Length == 0)
                    return;
                }
            char ch = Char.ToLower(str[0], this.Culture);
            int hashcode = ch % TOKEN_HASH_SIZE;
            int hashProbe = 1 + ch % SECOND_PRIME;
            do {
                value = hashTable[hashcode];
                if (value == null) {
                    //// Console.WriteLine("   Put Key: {0} in {1}", str, hashcode);
                    hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);
                    return;
                } else {
                    // Collision happens. Find another slot.
                    if (str.Length >= value.tokenString.Length) {
                        // If there are two tokens with the same prefix, we have to make sure that the longer token should be at the front of
                        // the shorter ones.
                        if (String.Compare(str, 0, value.tokenString, 0, value.tokenString.Length, this.Culture, CompareOptions.IgnoreCase) == 0) {
                            if (str.Length > value.tokenString.Length) {
                                // The str to be inserted has the same prefix as the current token, and str is longer.
                                // Insert str into this node, and shift every node behind it.
                                InsertAtCurrentHashNode(hashTable, str, ch, tokenType, tokenValue, i, hashcode, hashProbe);
                                return;
                            } else {
                                // Same token.  If they have different types (regular token vs separator token).  Add them.
                                // If we have the same regular token or separator token in the hash already, do NOT update the hash.
                                // Therefore, the order of inserting token is significant here regarding what tokenType will be kept in the hash.


                                //
                                // Check the current value of RegularToken (stored in the lower 8-bit of tokenType) , and insert the tokenType into the hash ONLY when we don't have a RegularToken yet.
                                // Also check the current value of SeparatorToken (stored in the upper 8-bit of token), and insert the tokenType into the hash ONLY when we don't have the SeparatorToken yet.
                                //

                                int nTokenType = (int)tokenType;
                                int nCurrentTokenTypeInHash = (int)value.tokenType;

                                // The idea behind this check is:
                                // - if the app is targetting 4.5.1 or above OR the compat flag is set, use the correct behavior by default.
                                // - if the app is targetting 4.5 or below AND the compat switch is set, use the correct behavior
                                // - if the app is targetting 4.5 or below AND the compat switch is NOT set, use the incorrect behavior
                                if (preferExistingTokens || BinaryCompatibility.TargetsAtLeast_Desktop_V4_5_1)
                                {
                                    if (((nCurrentTokenTypeInHash & (int)TokenType.RegularTokenMask) == 0) && ((nTokenType & (int)TokenType.RegularTokenMask) != 0) ||
                                       ((nCurrentTokenTypeInHash & (int)TokenType.SeparatorTokenMask) == 0) && ((nTokenType & (int)TokenType.SeparatorTokenMask) != 0))
                                    {
                                        value.tokenType |= tokenType;
                                        if (tokenValue != 0)
                                        {
                                            value.tokenValue = tokenValue;
                                        }
                                    }
                                }
                                else
                                {
                                    // The following logic is incorrect and causes updates to happen depending on the bitwise relationship between the existing token type and the
                                    // the stored token type.  It was this way in .NET 4 RTM.  The behavior above is correct and will be adopted going forward.

                                    if ((((nTokenType | nCurrentTokenTypeInHash) & (int)TokenType.RegularTokenMask) == nTokenType) ||
                                       (((nTokenType | nCurrentTokenTypeInHash) & (int)TokenType.SeparatorTokenMask) == nTokenType))
                                    {
                                        value.tokenType |= tokenType;
                                        if (tokenValue != 0)
                                        {
                                            value.tokenValue = tokenValue;
                                        }
                                    }
                                }
                                // The token to be inserted is already in the table.  Skip it.
                            }
                        }
                    }
                }
                //// Console.WriteLine("  COLLISION. Old Key: {0}, New Key: {1}", hashTable[hashcode].tokenString, str);
                i++;
                hashcode += hashProbe;
                if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
            } while (i < TOKEN_HASH_SIZE);
            Contract.Assert(true, "The hashtable is full.  This should not happen.");
        }
        internal TokenHashValue[] CreateTokenHashTable() {
            TokenHashValue[] temp = m_dtfiTokenHash;
            if (temp == null) {
                temp = new TokenHashValue[TOKEN_HASH_SIZE];
                
                InsertHash(temp, ",", TokenType.IgnorableSymbol, 0);
                InsertHash(temp, ".", TokenType.IgnorableSymbol, 0);
                
                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 (CultureName.Equals("sq-AL")) {
                    // Algerian allows time formats like "12:00.PD"
                    InsertHash(temp, "." + this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
                    InsertHash(temp, "." + 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 (LanguageName.Equals(KoreanLangName)) {
                    // Korean suffix
                    InsertHash(temp, KoreanHourSuff, TokenType.SEP_HourSuff, 0);
                    InsertHash(temp, KoreanMinuteSuff, TokenType.SEP_MinuteSuff, 0);
                    InsertHash(temp, KoreanSecondSuff, TokenType.SEP_SecondSuff, 0);
                }

                String[] dateWords = null;
                DateTimeFormatInfoScanner scanner = null;

                // Get the all of the long date pattern.  The getter will check if the default LongDatePattern
                // is in the standard list or not.  If not, m_scanDateWords will be true, and we will
                // need to scan the date words.
                // Note that dateWords is used as a temp buffer here.  It will be reset as the real date words later.
                if (!m_scanDateWords)
                {
                        dateWords = ClonedAllLongDatePatterns;
                }
                if (m_scanDateWords || m_cultureTableRecord.IsSynthetic)
                {
                    scanner = new DateTimeFormatInfoScanner();
                    // Enumarate all LongDatePatterns, and get the DateWords and scan for month postfix.
                    m_dateWords = dateWords = scanner.GetDateWordsOfDTFI(this);
                    // Ensure the formatflags is initialized.
                    DateTimeFormatFlags flag = FormatFlags;
                    m_scanDateWords = false;
                } else
                {
                    // Use the table value.
                    dateWords = this.DateWords;;
                }

                // For some cultures, the date separator works more like a comma, being allowed before or after any date part.
                // In this cultures, we do not use normal date separator since we disallow date separator after a date terminal state.
                // This is determinted 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 (CultureName.Equals("eu-ES")) {
                                    // Basque has date words with leading dots
                                    InsertHash(temp, "." + 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 (CultureName.Equals("gl-ES")) {
                    //
                    // Special case for gl-ES.  It has a potential incorrect format in year/month: MMMM'de 'yyyy.
                    // It probably has to be MMMM' de 'yyyy.
                    //

                    // We keep this so that we can still parse dates formatted in the older version.
                    for (int i = 1; i <= 13; i++) {
                        String str;
                        //str = internalGetMonthName(i, MonthNameStyles.Regular, false);
                        // 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 = GetMonthName(i);
                        if (str.Length > 0) {
                            // Insert the month name with the postfix first, so it can be matched first.
                            InsertHash(temp, str + "de", 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);

                if (CultureName.Equals("ky-KG")) {
                    // For some cultures, the date separator works more like a comma, being allowed before or after any date part
                    InsertHash(temp, alternativeDateSeparator, TokenType.IgnorableSymbol, 0);
                }
                else {
                    InsertHash(temp, alternativeDateSeparator, TokenType.SEP_Date, 0);
                }

                m_dtfiTokenHash = temp;
            }
            return (temp);
        }