Ejemplo n.º 1
0
        //
        //  ProcessTerminalState
        //
        //  Actions: Validate the terminal state of a standard format parse.
        //           Sets result.parsedTimeSpan on success.
        // 
        // Calculates the resultant TimeSpan from the TimeSpanRawInfo
        //
        // try => +InvariantPattern, -InvariantPattern, +LocalizedPattern, -LocalizedPattern
        // 1) Verify Start matches
        // 2) Verify End matches
        // 3) 1 number  => d
        //    2 numbers => h:m
        //    3 numbers => h:m:s | d.h:m | h:m:.f
        //    4 numbers => h:m:s.f | d.h:m:s | d.h:m:.f
        //    5 numbers => d.h:m:s.f
        private static Boolean ProcessTerminalState(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result) {
            if (raw.lastSeenTTT == TTT.Num) {
                TimeSpanToken tok = new TimeSpanToken();
                tok.ttt = TTT.Sep;
                tok.sep = String.Empty;
                if (!raw.ProcessToken(ref tok, ref result)) {
                    result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
                    return false;
                }
            }

            switch (raw.NumCount) {
                case 1:
                    return ProcessTerminal_D(ref raw, style, ref result);
                case 2:
                    return ProcessTerminal_HM(ref raw, style, ref result);
                case 3:
                    return ProcessTerminal_HM_S_D(ref raw, style, ref result);
                case 4:
                    return ProcessTerminal_HMS_F_D(ref raw, style, ref result);
                case 5:
                    return ProcessTerminal_DHMSF(ref raw, style, ref result);
                default:
                    result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
                    return false;
            }
        }       
Ejemplo n.º 2
0
        static bool TryTimeToTicks(bool positive, TimeSpanToken days, TimeSpanToken hours, TimeSpanToken minutes, TimeSpanToken seconds, TimeSpanToken fraction, out long result) {
            if (days.IsInvalidNumber(maxDays, unlimitedDigits)
             || hours.IsInvalidNumber(maxHours, unlimitedDigits)
             || minutes.IsInvalidNumber(maxMinutes, unlimitedDigits)
             || seconds.IsInvalidNumber(maxSeconds, unlimitedDigits)
             || fraction.IsInvalidNumber(maxFraction, maxFractionDigits)) {
                result = 0;
                return false;
            }

            Int64 ticks = ((Int64)days.num * 3600 * 24 + (Int64)hours.num * 3600 + (Int64)minutes.num * 60 + seconds.num) * 1000;
            if (ticks > TimeSpan.MaxMilliSeconds || ticks < TimeSpan.MinMilliSeconds) {
                result = 0;
                return false;
            }

            // Normalize the fraction component
            //
            // string representation => (zeroes,num) => resultant fraction ticks
            // ---------------------    ------------    ------------------------
            // ".9999999"            => (0,9999999)  => 9,999,999 ticks (same as constant maxFraction)
            // ".1"                  => (0,1)        => 1,000,000 ticks
            // ".01"                 => (1,1)        =>   100,000 ticks
            // ".001"                => (2,1)        =>    10,000 ticks
            long f = fraction.num;
            if (f != 0) {
                long lowerLimit = TimeSpan.TicksPerTenthSecond;
                if (fraction.zeroes > 0) {
                    long divisor = (long)Math.Pow(10, fraction.zeroes);
                    lowerLimit = lowerLimit / divisor;
                }
                while (f < lowerLimit) {
                    f *= 10;
                }
            }
            result = ((long)ticks * TimeSpan.TicksPerMillisecond) + f;
            if (positive && result < 0) {
                result = 0;
                return false;
            }
            return true;
        }
Ejemplo n.º 3
0
 private bool AddNum(TimeSpanToken num, ref TimeSpanResult result) {
     if (NumCount >= MaxNumericTokens || tokenCount >= MaxTokens) {
         result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan", null);
         return false;
     }
     numbers[NumCount++] = num;   
     tokenCount++;
     return true;
 }
Ejemplo n.º 4
0
            internal Boolean ProcessToken(ref TimeSpanToken tok, ref TimeSpanResult result) {
                if (tok.ttt == TTT.NumOverflow) {
                    result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge", null);
                    return false;
                }
                if (tok.ttt != TTT.Sep && tok.ttt != TTT.Num) {
                    // Some unknown token or a repeat token type in the input
                    result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan", null);
                    return false;
                }

                switch (tok.ttt) {
                    case TTT.Sep:
                        if (!AddSep(tok.sep, ref result)) return false;
                        break;
                    case TTT.Num:
                        if (tokenCount == 0) {
                            if (!AddSep(String.Empty, ref result)) return false;
                        }
                        if (!AddNum(tok, ref result)) return false;
                        break;
                    default:
                        break;
                }

                lastSeenTTT = tok.ttt;
                Debug.Assert(tokenCount == (SepCount + NumCount), "tokenCount == (SepCount + NumCount)");
                return true;
            }
Ejemplo n.º 5
0
            // used by the parsing routines that operate on standard-formats
            internal TimeSpanToken GetNextToken() {
                Debug.Assert(m_pos > -1);

                TimeSpanToken tok = new TimeSpanToken();
                char ch = CurrentChar;

                if (ch == (char)0) {
                    tok.ttt = TTT.End;
                    return tok;
                }

                if (ch >= '0' && ch <= '9') {                   
                    tok.ttt = TTT.Num;
                    tok.num = 0;
                    tok.zeroes = 0;
                    do {
                        if ((tok.num & 0xF0000000) != 0) {
                            tok.ttt = TTT.NumOverflow;
                            return tok;
                        }
                        tok.num = tok.num * 10 + ch - '0';
                        if (tok.num == 0) tok.zeroes++;
                        if (tok.num < 0) {
                            tok.ttt = TTT.NumOverflow;
                            return tok;
                        }
                        ch = NextChar;
                    } while (ch >= '0' && ch <= '9');
                    return tok;
                }
                else {
                    tok.ttt = TTT.Sep;
                    int startIndex = m_pos;
                    int length = 0;

                    while (ch != (char)0 && (ch < '0' || '9' < ch)) {
                        ch = NextChar;
                        length++;
                    }
                    tok.sep = m_value.Substring(startIndex, length);
                    return tok;
                }
            }
 private static bool TryTimeToTicks(bool positive, TimeSpanToken days, TimeSpanToken hours, TimeSpanToken minutes, TimeSpanToken seconds, TimeSpanToken fraction, out long result)
 {
     if ((days.IsInvalidNumber(0xa2e3ff, -1) || hours.IsInvalidNumber(0x17, -1)) || ((minutes.IsInvalidNumber(0x3b, -1) || seconds.IsInvalidNumber(0x3b, -1)) || fraction.IsInvalidNumber(0x98967f, 7)))
     {
         result = 0L;
         return false;
     }
     long num = (((((days.num * 0xe10L) * 0x18L) + (hours.num * 0xe10L)) + (minutes.num * 60L)) + seconds.num) * 0x3e8L;
     if ((num > 0x346dc5d638865L) || (num < -922337203685477L))
     {
         result = 0L;
         return false;
     }
     long num2 = fraction.num;
     if (num2 != 0L)
     {
         long num3 = 0xf4240L;
         if (fraction.zeroes > 0)
         {
             long num4 = (long) Math.Pow(10.0, (double) fraction.zeroes);
             num3 /= num4;
         }
         while (num2 < num3)
         {
             num2 *= 10L;
         }
     }
     result = (num * 0x2710L) + num2;
     if (positive && (result < 0L))
     {
         result = 0L;
         return false;
     }
     return true;
 }