Example #1
0
        private void ParseNumber()
        {
            ShiftBufferIfNeeded();

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

              ReadNumberIntoBuffer();

              _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();

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

              numberValue = integer;
            }
            else
            {
              string number = _stringReference.ToString();

              numberValue = Convert.ToInt32(number, CultureInfo.InvariantCulture);
            }

            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();

              // 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);
            }
            else
            {
              string number = _stringReference.ToString();

              numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
            }

            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();

              numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
                          ? Convert.ToInt64(number, 16)
                          : Convert.ToInt64(number, 8);
              numberType = JsonToken.Integer;
            }
            else
            {
              string number = _stringReference.ToString();

              // it's faster to do 3 indexof with single characters than an indexofany
              if (number.IndexOf('.') != -1 || number.IndexOf('E') != -1 || number.IndexOf('e') != -1)
              {
            numberValue = Convert.ToDouble(number, CultureInfo.InvariantCulture);
            numberType = JsonToken.Float;
              }
              else
              {
            try
            {
              numberValue = Convert.ToInt64(number, CultureInfo.InvariantCulture);
            }
            catch (OverflowException ex)
            {
              throw new JsonReaderException("JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, number), ex);
            }

            numberType = JsonToken.Integer;
              }
            }
              }

              ClearRecentString();

              SetToken(numberType, numberValue);
        }
Example #2
0
        private void ParseConstructor()
        {
            if (MatchValueWithTrailingSeperator("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 CreateReaderException(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 CreateReaderException(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 CreateReaderException(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));

            _charPos++;

            ClearRecentString();

            SetToken(JsonToken.StartConstructor, constructorName);
              }
        }
Example #3
0
        private void ParseComment()
        {
            // should have already parsed / character before reaching this method
              _charPos++;

              if (!EnsureChars(1, false) || _chars[_charPos] != '*')
            throw CreateReaderException(this, "Error parsing comment. Expected: *, got {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
              else
            _charPos++;

              int initialPosition = _charPos;

              bool commentFinished = false;

              while (!commentFinished)
              {
            switch (_chars[_charPos])
            {
              case '\0':
            if (_charsUsed == _charPos)
            {
              if (ReadData(true) == 0)
                throw CreateReaderException(this, "Unexpected end while parsing comment.");
            }
            else
            {
              _charPos++;
            }
            break;
              case '*':
            _charPos++;

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

                _charPos++;
                commentFinished = true;
              }
            }
            break;
              case StringUtils.CarriageReturn:
            ProcessCarriageReturn(true);
            break;
              case StringUtils.LineFeed:
            ProcessLineFeed();
            break;
              default:
            _charPos++;
            break;
            }
              }

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

              ClearRecentString();
        }
Example #4
0
        private void ClearRecentString()
        {
            if (_buffer != null)
            _buffer.Position = 0;

              _stringReference = new StringReference();
        }
Example #5
0
        private void ReadStringIntoBuffer(char quote)
        {
            int charPos = _charPos;
              int initialPosition = _charPos;
              int lastWritePosition = _charPos;
              StringBuffer buffer = null;

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

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

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

            char currentChar = _chars[charPos];

            char writeChar;

            switch (currentChar)
            {
              case 'b':
                charPos++;
                writeChar = '\b';
                break;
              case 't':
                charPos++;
                writeChar = '\t';
                break;
              case 'n':
                charPos++;
                writeChar = '\n';
                break;
              case 'f':
                charPos++;
                writeChar = '\f';
                break;
              case 'r':
                charPos++;
                writeChar = '\r';
                break;
              case '\\':
                charPos++;
                writeChar = '\\';
                break;
              case '"':
              case '\'':
              case '/':
                writeChar = currentChar;
                charPos++;
                break;
              case 'u':
                charPos++;
                _charPos = charPos;
                if (EnsureChars(4, true))
                {
                  string hexValues = new string(_chars, charPos, 4);
                  char hexChar = Convert.ToChar(int.Parse(hexValues, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo));
                  writeChar = hexChar;

                  charPos += 4;
                }
                else
                {
                  _charPos = charPos;
                  throw CreateReaderException(this, "Unexpected end while parsing unicode character.");
                }
                break;
              default:
                charPos++;
                _charPos = charPos;
                throw CreateReaderException(this, "Bad JSON escape sequence: {0}.".FormatWith(CultureInfo.InvariantCulture, @"\" + currentChar));
            }

            if (buffer == null)
              buffer = GetBuffer();

            if (escapeStartPos > lastWritePosition)
            {
              buffer.Append(_chars, lastWritePosition, escapeStartPos - lastWritePosition);
            }

            buffer.Append(writeChar);

            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
              {
                if (buffer == null)
                  buffer = GetBuffer();

                if (charPos > lastWritePosition)
                  buffer.Append(_chars, lastWritePosition, charPos - lastWritePosition);

                _stringReference = new StringReference(buffer.GetInternalBuffer(), 0, buffer.Position);
              }

              charPos++;
              _charPos = charPos;
              return;
            }
            break;
            }
              }
        }
Example #6
0
        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 CreateReaderException(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 CreateReaderException(this, "Invalid JavaScript property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
            }
              }
        }