示例#1
0
        internal static bool TryParseDateTimeOffsetIso(StringReference text, out DateTimeOffset dt)
        {
            DateTimeParser dateTimeParser = new DateTimeParser();

            if (!dateTimeParser.Parse(text.Chars, text.StartIndex, text.Length))
            {
                dt = default(DateTimeOffset);
                return(false);
            }

            DateTime d = CreateDateTime(dateTimeParser);

            TimeSpan offset;

            switch (dateTimeParser.Zone)
            {
            case ParserTimeZone.Utc:
                offset = new TimeSpan(0L);
                break;

            case ParserTimeZone.LocalWestOfUtc:
                offset = new TimeSpan(-dateTimeParser.ZoneHour, -dateTimeParser.ZoneMinute, 0);
                break;

            case ParserTimeZone.LocalEastOfUtc:
                offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0);
                break;

            default:
                offset = TimeZoneInfo.Local.GetUtcOffset(d);
                break;
            }

            long ticks = d.Ticks - offset.Ticks;

            if (ticks < 0 || ticks > 3155378975999999999)
            {
                dt = default(DateTimeOffset);
                return(false);
            }

            dt = new DateTimeOffset(d, offset);
            return(true);
        }
示例#2
0
        public static bool StartsWith(this StringReference s, string text)
        {
            if (text.Length > s.Length)
            {
                return(false);
            }

            char[] chars = s.Chars;

            for (int i = 0; i < text.Length; i++)
            {
                if (text[i] != chars[i + s.StartIndex])
                {
                    return(false);
                }
            }

            return(true);
        }
        private static bool TryParseDateTimeMicrosoft(StringReference text, DateTimeZoneHandling dateTimeZoneHandling, out DateTime dt)
        {
            long ticks;
            TimeSpan offset;
            DateTimeKind kind;

            if (!TryParseMicrosoftDate(text, out ticks, out offset, out kind))
            {
                dt = default(DateTime);
                return false;
            }

            DateTime utcDateTime = ConvertJavaScriptTicksToDateTime(ticks);

            switch (kind)
            {
                case DateTimeKind.Unspecified:
                    dt = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
                    break;
                case DateTimeKind.Local:
                    dt = utcDateTime.ToLocalTime();
                    break;
                default:
                    dt = utcDateTime;
                    break;
            }

            dt = EnsureDateTime(dt, dateTimeZoneHandling);
            return true;
        }
        private static bool TryParseMicrosoftDate(StringReference text, out long ticks, out TimeSpan offset, out DateTimeKind kind)
        {
            kind = DateTimeKind.Utc;

            int index = text.IndexOf('+', 7, text.Length - 8);

            if (index == -1)
            {
                index = text.IndexOf('-', 7, text.Length - 8);
            }

            if (index != -1)
            {
                kind = DateTimeKind.Local;

                if (!TryReadOffset(text, index + text.StartIndex, out offset))
                {
                    ticks = 0;
                    return false;
                }
            }
            else
            {
                offset = TimeSpan.Zero;
                index = text.Length - 2;
            }

            return (ConvertUtils.Int64TryParse(text.Chars, 6 + text.StartIndex, index - 6, out ticks) == ParseResult.Success);
        }
        internal static bool TryParseDateTimeOffset(StringReference s, string dateFormatString, CultureInfo culture, out DateTimeOffset dt)
        {
            if (s.Length > 0)
            {
                int i = s.StartIndex;
                if (s[i] == '/')
                {
                    if (s.Length >= 9 && s.StartsWith("/Date(") && s.EndsWith(")/"))
                    {
                        if (TryParseDateTimeOffsetMicrosoft(s, out dt))
                        {
                            return true;
                        }
                    }
                }
                else if (s.Length >= 19 && s.Length <= 40 && char.IsDigit(s[i]) && s[i + 10] == 'T')
                {
                    if (TryParseDateTimeOffsetIso(s, out dt))
                    {
                        return true;
                    }
                }

                if (!string.IsNullOrEmpty(dateFormatString))
                {
                    if (TryParseDateTimeOffsetExact(s.ToString(), dateFormatString, culture, out dt))
                    {
                        return true;
                    }
                }
            }

            dt = default(DateTimeOffset);
            return false;
        }
        internal static bool TryParseDateTimeOffsetIso(StringReference text, out DateTimeOffset dt)
        {
            DateTimeParser dateTimeParser = new DateTimeParser();
            if (!dateTimeParser.Parse(text.Chars, text.StartIndex, text.Length))
            {
                dt = default(DateTimeOffset);
                return false;
            }

            DateTime d = CreateDateTime(dateTimeParser);

            TimeSpan offset;

            switch (dateTimeParser.Zone)
            {
                case ParserTimeZone.Utc:
                    offset = new TimeSpan(0L);
                    break;
                case ParserTimeZone.LocalWestOfUtc:
                    offset = new TimeSpan(-dateTimeParser.ZoneHour, -dateTimeParser.ZoneMinute, 0);
                    break;
                case ParserTimeZone.LocalEastOfUtc:
                    offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0);
                    break;
                default:
                    offset = TimeZoneInfo.Local.GetUtcOffset(d);
                    break;
            }

            long ticks = d.Ticks - offset.Ticks;
            if (ticks < 0 || ticks > 3155378975999999999)
            {
                dt = default(DateTimeOffset);
                return false;
            }

            dt = new DateTimeOffset(d, offset);
            return true;
        }
        internal static bool TryParseDateTimeIso(StringReference text, DateTimeZoneHandling dateTimeZoneHandling, out DateTime dt)
        {
            DateTimeParser dateTimeParser = new DateTimeParser();
            if (!dateTimeParser.Parse(text.Chars, text.StartIndex, text.Length))
            {
                dt = default(DateTime);
                return false;
            }

            DateTime d = CreateDateTime(dateTimeParser);

            long ticks;

            switch (dateTimeParser.Zone)
            {
                case ParserTimeZone.Utc:
                    d = new DateTime(d.Ticks, DateTimeKind.Utc);
                    break;

                case ParserTimeZone.LocalWestOfUtc:
                {
                    TimeSpan offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0);
                    ticks = d.Ticks + offset.Ticks;
                    if (ticks <= DateTime.MaxValue.Ticks)
                    {
                        d = new DateTime(ticks, DateTimeKind.Utc).ToLocalTime();
                    }
                    else
                    {
                        ticks += d.GetUtcOffset().Ticks;
                        if (ticks > DateTime.MaxValue.Ticks)
                        {
                            ticks = DateTime.MaxValue.Ticks;
                        }

                        d = new DateTime(ticks, DateTimeKind.Local);
                    }
                    break;
                }
                case ParserTimeZone.LocalEastOfUtc:
                {
                    TimeSpan offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0);
                    ticks = d.Ticks - offset.Ticks;
                    if (ticks >= DateTime.MinValue.Ticks)
                    {
                        d = new DateTime(ticks, DateTimeKind.Utc).ToLocalTime();
                    }
                    else
                    {
                        ticks += d.GetUtcOffset().Ticks;
                        if (ticks < DateTime.MinValue.Ticks)
                        {
                            ticks = DateTime.MinValue.Ticks;
                        }

                        d = new DateTime(ticks, DateTimeKind.Local);
                    }
                    break;
                }
            }

            dt = EnsureDateTime(d, dateTimeZoneHandling);
            return true;
        }
        private void ParseConstructor()
        {
            if (MatchValueWithTrailingSeparator("new"))
            {
                EatWhitespace(false);

                int initialPosition = _charPos;
                int endPosition;

                while (true)
                {
                    char currentChar = _chars[_charPos];
                    if (currentChar == '\0')
                    {
                        if (_charsUsed == _charPos)
                        {
                            if (ReadData(true) == 0)
                            {
                                throw JsonReaderException.Create(this, "Unexpected end while parsing constructor.");
                            }
                        }
                        else
                        {
                            endPosition = _charPos;
                            _charPos++;
                            break;
                        }
                    }
                    else if (char.IsLetterOrDigit(currentChar))
                    {
                        _charPos++;
                    }
                    else if (currentChar == StringUtils.CarriageReturn)
                    {
                        endPosition = _charPos;
                        ProcessCarriageReturn(true);
                        break;
                    }
                    else if (currentChar == StringUtils.LineFeed)
                    {
                        endPosition = _charPos;
                        ProcessLineFeed();
                        break;
                    }
                    else if (char.IsWhiteSpace(currentChar))
                    {
                        endPosition = _charPos;
                        _charPos++;
                        break;
                    }
                    else if (currentChar == '(')
                    {
                        endPosition = _charPos;
                        break;
                    }
                    else
                    {
                        throw JsonReaderException.Create(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
                    }
                }

                _stringReference = new StringReference(_chars, initialPosition, endPosition - initialPosition);
                string constructorName = _stringReference.ToString();

                EatWhitespace(false);

                if (_chars[_charPos] != '(')
                {
                    throw JsonReaderException.Create(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
                }

                _charPos++;

                ClearRecentString();

                SetToken(JsonToken.StartConstructor, constructorName);
            }
            else
            {
                throw JsonReaderException.Create(this, "Unexpected content while parsing JSON.");
            }
        }
 private void ClearRecentString()
 {
     _stringBuffer.Position = 0;
     _stringReference = new StringReference();
 }
        private void ParseUnquotedProperty()
        {
            int initialPosition = _charPos;

            // parse unquoted property name until whitespace or colon
            while (true)
            {
                switch (_chars[_charPos])
                {
                    case '\0':
                        if (_charsUsed == _charPos)
                        {
                            if (ReadData(true) == 0)
                            {
                                throw JsonReaderException.Create(this, "Unexpected end while parsing unquoted property name.");
                            }

                            break;
                        }

                        _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
                        return;
                    default:
                        char currentChar = _chars[_charPos];

                        if (ValidIdentifierChar(currentChar))
                        {
                            _charPos++;
                            break;
                        }
                        else if (char.IsWhiteSpace(currentChar) || currentChar == ':')
                        {
                            _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
                            return;
                        }

                        throw JsonReaderException.Create(this, "Invalid JavaScript property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
                }
            }
        }
        private void ReadStringIntoBuffer(char quote)
        {
            int charPos = _charPos;
            int initialPosition = _charPos;
            int lastWritePosition = _charPos;
            _stringBuffer.Position = 0;

            while (true)
            {
                switch (_chars[charPos++])
                {
                    case '\0':
                        if (_charsUsed == charPos - 1)
                        {
                            charPos--;

                            if (ReadData(true) == 0)
                            {
                                _charPos = charPos;
                                throw JsonReaderException.Create(this, "Unterminated string. Expected delimiter: {0}.".FormatWith(CultureInfo.InvariantCulture, quote));
                            }
                        }
                        break;
                    case '\\':
                        _charPos = charPos;
                        if (!EnsureChars(0, true))
                        {
                            throw JsonReaderException.Create(this, "Unterminated string. Expected delimiter: {0}.".FormatWith(CultureInfo.InvariantCulture, quote));
                        }

                        // start of escape sequence
                        int escapeStartPos = charPos - 1;

                        char currentChar = _chars[charPos];
                        charPos++;

                        char writeChar;

                        switch (currentChar)
                        {
                            case 'b':
                                writeChar = '\b';
                                break;
                            case 't':
                                writeChar = '\t';
                                break;
                            case 'n':
                                writeChar = '\n';
                                break;
                            case 'f':
                                writeChar = '\f';
                                break;
                            case 'r':
                                writeChar = '\r';
                                break;
                            case '\\':
                                writeChar = '\\';
                                break;
                            case '"':
                            case '\'':
                            case '/':
                                writeChar = currentChar;
                                break;
                            case 'u':
                                _charPos = charPos;
                                writeChar = ParseUnicode();

                                if (StringUtils.IsLowSurrogate(writeChar))
                                {
                                    // low surrogate with no preceding high surrogate; this char is replaced
                                    writeChar = UnicodeReplacementChar;
                                }
                                else if (StringUtils.IsHighSurrogate(writeChar))
                                {
                                    bool anotherHighSurrogate;

                                    // loop for handling situations where there are multiple consecutive high surrogates
                                    do
                                    {
                                        anotherHighSurrogate = false;

                                        // potential start of a surrogate pair
                                        if (EnsureChars(2, true) && _chars[_charPos] == '\\' && _chars[_charPos + 1] == 'u')
                                        {
                                            char highSurrogate = writeChar;

                                            _charPos += 2;
                                            writeChar = ParseUnicode();

                                            if (StringUtils.IsLowSurrogate(writeChar))
                                            {
                                                // a valid surrogate pair!
                                            }
                                            else if (StringUtils.IsHighSurrogate(writeChar))
                                            {
                                                // another high surrogate; replace current and start check over
                                                highSurrogate = UnicodeReplacementChar;
                                                anotherHighSurrogate = true;
                                            }
                                            else
                                            {
                                                // high surrogate not followed by low surrogate; original char is replaced
                                                highSurrogate = UnicodeReplacementChar;
                                            }

                                            EnsureBufferNotEmpty();

                                            WriteCharToBuffer(highSurrogate, lastWritePosition, escapeStartPos);
                                            lastWritePosition = _charPos;
                                        }
                                        else
                                        {
                                            // there are not enough remaining chars for the low surrogate or is not follow by unicode sequence
                                            // replace high surrogate and continue on as usual
                                            writeChar = UnicodeReplacementChar;
                                        }
                                    } while (anotherHighSurrogate);
                                }

                                charPos = _charPos;
                                break;
                            default:
                                _charPos = charPos;
                                throw JsonReaderException.Create(this, "Bad JSON escape sequence: {0}.".FormatWith(CultureInfo.InvariantCulture, @"\" + currentChar));
                        }

                        EnsureBufferNotEmpty();
                        WriteCharToBuffer(writeChar, lastWritePosition, escapeStartPos);

                        lastWritePosition = charPos;
                        break;
                    case StringUtils.CarriageReturn:
                        _charPos = charPos - 1;
                        ProcessCarriageReturn(true);
                        charPos = _charPos;
                        break;
                    case StringUtils.LineFeed:
                        _charPos = charPos - 1;
                        ProcessLineFeed();
                        charPos = _charPos;
                        break;
                    case '"':
                    case '\'':
                        if (_chars[charPos - 1] == quote)
                        {
                            charPos--;

                            if (initialPosition == lastWritePosition)
                            {
                                _stringReference = new StringReference(_chars, initialPosition, charPos - initialPosition);
                            }
                            else
                            {
                                EnsureBufferNotEmpty();

                                if (charPos > lastWritePosition)
                                {
                                    _stringBuffer.Append(_arrayPool, _chars, lastWritePosition, charPos - lastWritePosition);
                                }

                                _stringReference = new StringReference(_stringBuffer.InternalBuffer, 0, _stringBuffer.Position);
                            }

                            charPos++;
                            _charPos = charPos;
                            return;
                        }
                        break;
                }
            }
        }
示例#12
0
        private void ClearRecentString()
        {
            if (_buffer != null)
                _buffer.Position = 0;

            _stringReference = new StringReference();
        }
示例#13
0
        private void ParseComment()
        {
            // should have already parsed / character before reaching this method
            _charPos++;

            if (!EnsureChars(1, false))
                throw JsonReaderException.Create(this, "Unexpected end while parsing comment.");

            bool singlelineComment;

            if (_chars[_charPos] == '*')
                singlelineComment = false;
            else if (_chars[_charPos] == '/')
                singlelineComment = true;
            else
                throw JsonReaderException.Create(this, "Error parsing comment. Expected: *, got {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));

            _charPos++;

            int initialPosition = _charPos;

            bool commentFinished = false;

            while (!commentFinished)
            {
                switch (_chars[_charPos])
                {
                    case '\0':
                        if (_charsUsed == _charPos)
                        {
                            if (ReadData(true) == 0)
                            {
                                if (!singlelineComment)
                                    throw JsonReaderException.Create(this, "Unexpected end while parsing comment.");

                                _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
                                commentFinished = true;
                            }
                        }
                        else
                        {
                            _charPos++;
                        }
                        break;
                    case '*':
                        _charPos++;

                        if (!singlelineComment)
                        {
                            if (EnsureChars(0, true))
                            {
                                if (_chars[_charPos] == '/')
                                {
                                    _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition - 1);

                                    _charPos++;
                                    commentFinished = true;
                                }
                            }
                        }
                        break;
                    case StringUtils.CarriageReturn:
                        if (singlelineComment)
                        {
                            _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
                            commentFinished = true;
                        }
                        ProcessCarriageReturn(true);
                        break;
                    case StringUtils.LineFeed:
                        if (singlelineComment)
                        {
                            _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
                            commentFinished = true;
                        }
                        ProcessLineFeed();
                        break;
                    default:
                        _charPos++;
                        break;
                }
            }

            SetToken(JsonToken.Comment, _stringReference.ToString());

            ClearRecentString();
        }
        private static bool TryParseDateTimeOffsetMicrosoft(StringReference text, out DateTimeOffset dt)
        {
            long ticks;
            TimeSpan offset;
            DateTimeKind kind;

            if (!TryParseMicrosoftDate(text, out ticks, out offset, out kind))
            {
                dt = default(DateTime);
                return false;
            }

            DateTime utcDateTime = ConvertJavaScriptTicksToDateTime(ticks);

            dt = new DateTimeOffset(utcDateTime.Add(offset).Ticks, offset);
            return true;
        }
        private void ParseNumber(ReadType readType)
        {
            ShiftBufferIfNeeded();

            char firstChar = _chars[_charPos];
            int initialPosition = _charPos;

            ReadNumberIntoBuffer();

            // set state to PostValue now so that if there is an error parsing the number then the reader can continue
            SetPostValueState(true);

            _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);

            object numberValue;
            JsonToken numberType;

            bool singleDigit = (char.IsDigit(firstChar) && _stringReference.Length == 1);
            bool nonBase10 = (firstChar == '0' && _stringReference.Length > 1 && _stringReference.Chars[_stringReference.StartIndex + 1] != '.' && _stringReference.Chars[_stringReference.StartIndex + 1] != 'e' && _stringReference.Chars[_stringReference.StartIndex + 1] != 'E');

            if (readType == ReadType.ReadAsInt32)
            {
                if (singleDigit)
                {
                    // digit char values start at 48
                    numberValue = firstChar - 48;
                }
                else if (nonBase10)
                {
                    string number = _stringReference.ToString();

                    try
                    {
                        int integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt32(number, 16) : Convert.ToInt32(number, 8);

                        numberValue = integer;
                    }
                    catch (Exception ex)
                    {
                        throw JsonReaderException.Create(this, "Input string '{0}' is not a valid integer.".FormatWith(CultureInfo.InvariantCulture, number), ex);
                    }
                }
                else
                {
                    int value;
                    ParseResult parseResult = ConvertUtils.Int32TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out value);
                    if (parseResult == ParseResult.Success)
                    {
                        numberValue = value;
                    }
                    else if (parseResult == ParseResult.Overflow)
                    {
                        throw JsonReaderException.Create(this, "JSON integer {0} is too large or small for an Int32.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
                    }
                    else
                    {
                        throw JsonReaderException.Create(this, "Input string '{0}' is not a valid integer.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
                    }
                }

                numberType = JsonToken.Integer;
            }
            else if (readType == ReadType.ReadAsDecimal)
            {
                if (singleDigit)
                {
                    // digit char values start at 48
                    numberValue = (decimal)firstChar - 48;
                }
                else if (nonBase10)
                {
                    string number = _stringReference.ToString();

                    try
                    {
                        // decimal.Parse doesn't support parsing hexadecimal values
                        long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8);

                        numberValue = Convert.ToDecimal(integer);
                    }
                    catch (Exception ex)
                    {
                        throw JsonReaderException.Create(this, "Input string '{0}' is not a valid decimal.".FormatWith(CultureInfo.InvariantCulture, number), ex);
                    }
                }
                else
                {
                    string number = _stringReference.ToString();

                    decimal value;
                    if (decimal.TryParse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out value))
                    {
                        numberValue = value;
                    }
                    else
                    {
                        throw JsonReaderException.Create(this, "Input string '{0}' is not a valid decimal.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
                    }
                }

                numberType = JsonToken.Float;
            }
            else if (readType == ReadType.ReadAsDouble)
            {
                if (singleDigit)
                {
                    // digit char values start at 48
                    numberValue = (double)firstChar - 48;
                }
                else if (nonBase10)
                {
                    string number = _stringReference.ToString();

                    try
                    {
                        // double.Parse doesn't support parsing hexadecimal values
                        long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8);

                        numberValue = Convert.ToDouble(integer);
                    }
                    catch (Exception ex)
                    {
                        throw JsonReaderException.Create(this, "Input string '{0}' is not a valid double.".FormatWith(CultureInfo.InvariantCulture, number), ex);
                    }
                }
                else
                {
                    string number = _stringReference.ToString();

                    double value;
                    if (double.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out value))
                    {
                        numberValue = value;
                    }
                    else
                    {
                        throw JsonReaderException.Create(this, "Input string '{0}' is not a valid double.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
                    }
                }

                numberType = JsonToken.Float;
            }
            else
            {
                if (singleDigit)
                {
                    // digit char values start at 48
                    numberValue = (long)firstChar - 48;
                    numberType = JsonToken.Integer;
                }
                else if (nonBase10)
                {
                    string number = _stringReference.ToString();

                    try
                    {
                        numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8);
                    }
                    catch (Exception ex)
                    {
                        throw JsonReaderException.Create(this, "Input string '{0}' is not a valid number.".FormatWith(CultureInfo.InvariantCulture, number), ex);
                    }

                    numberType = JsonToken.Integer;
                }
                else
                {
                    long value;
                    ParseResult parseResult = ConvertUtils.Int64TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out value);
                    if (parseResult == ParseResult.Success)
                    {
                        numberValue = value;
                        numberType = JsonToken.Integer;
                    }
                    else if (parseResult == ParseResult.Overflow)
                    {
#if !(NET20 || NET35 || PORTABLE40 || PORTABLE)
                        string number = _stringReference.ToString();

                        if (number.Length > MaximumJavascriptIntegerCharacterLength)
                        {
                            throw JsonReaderException.Create(this, "JSON integer {0} is too large to parse.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
                        }

                        numberValue = BigIntegerParse(number, CultureInfo.InvariantCulture);
                        numberType = JsonToken.Integer;
#else
                        throw JsonReaderException.Create(this, "JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
#endif
                    }
                    else
                    {
                        string number = _stringReference.ToString();

                        if (_floatParseHandling == FloatParseHandling.Decimal)
                        {
                            decimal d;
                            if (decimal.TryParse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out d))
                            {
                                numberValue = d;
                            }
                            else
                            {
                                throw JsonReaderException.Create(this, "Input string '{0}' is not a valid decimal.".FormatWith(CultureInfo.InvariantCulture, number));
                            }
                        }
                        else
                        {
                            double d;
                            if (double.TryParse(number, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out d))
                            {
                                numberValue = d;
                            }
                            else
                            {
                                throw JsonReaderException.Create(this, "Input string '{0}' is not a valid number.".FormatWith(CultureInfo.InvariantCulture, number));
                            }
                        }

                        numberType = JsonToken.Float;
                    }
                }
            }

            ClearRecentString();

            // index has already been updated
            SetToken(numberType, numberValue, false);
        }
        private static bool TryReadOffset(StringReference offsetText, int startIndex, out TimeSpan offset)
        {
            bool negative = (offsetText[startIndex] == '-');

            int hours;
            if (ConvertUtils.Int32TryParse(offsetText.Chars, startIndex + 1, 2, out hours) != ParseResult.Success)
            {
                offset = default(TimeSpan);
                return false;
            }

            int minutes = 0;
            if (offsetText.Length - startIndex > 5)
            {
                if (ConvertUtils.Int32TryParse(offsetText.Chars, startIndex + 3, 2, out minutes) != ParseResult.Success)
                {
                    offset = default(TimeSpan);
                    return false;
                }
            }

            offset = TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes);
            if (negative)
            {
                offset = offset.Negate();
            }

            return true;
        }
示例#17
0
        internal static bool TryParseDateTimeIso(StringReference text, DateTimeZoneHandling dateTimeZoneHandling, out DateTime dt)
        {
            DateTimeParser dateTimeParser = new DateTimeParser();

            if (!dateTimeParser.Parse(text.Chars, text.StartIndex, text.Length))
            {
                dt = default(DateTime);
                return(false);
            }

            DateTime d = CreateDateTime(dateTimeParser);

            long ticks;

            switch (dateTimeParser.Zone)
            {
            case ParserTimeZone.Utc:
                d = new DateTime(d.Ticks, DateTimeKind.Utc);
                break;

            case ParserTimeZone.LocalWestOfUtc:
            {
                TimeSpan offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0);
                ticks = d.Ticks + offset.Ticks;
                if (ticks <= DateTime.MaxValue.Ticks)
                {
                    d = new DateTime(ticks, DateTimeKind.Utc).ToLocalTime();
                }
                else
                {
                    ticks += d.GetUtcOffset().Ticks;
                    if (ticks > DateTime.MaxValue.Ticks)
                    {
                        ticks = DateTime.MaxValue.Ticks;
                    }

                    d = new DateTime(ticks, DateTimeKind.Local);
                }
                break;
            }

            case ParserTimeZone.LocalEastOfUtc:
            {
                TimeSpan offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0);
                ticks = d.Ticks - offset.Ticks;
                if (ticks >= DateTime.MinValue.Ticks)
                {
                    d = new DateTime(ticks, DateTimeKind.Utc).ToLocalTime();
                }
                else
                {
                    ticks += d.GetUtcOffset().Ticks;
                    if (ticks < DateTime.MinValue.Ticks)
                    {
                        ticks = DateTime.MinValue.Ticks;
                    }

                    d = new DateTime(ticks, DateTimeKind.Local);
                }
                break;
            }
            }

            dt = EnsureDateTime(d, dateTimeZoneHandling);
            return(true);
        }