Exemple #1
0
        private unsafe string GetString(char *charBuffer)
        {
            Consume();
            var len = 0;

            while (true)
            {
                if (_isEnd)
                {
                    throw JsonParserException.UnexpectedEnd(_position);
                }
                var ch = _nextChar;
                if (ch == '"')
                {
                    Consume();
                    return(_stringBuffer.GetString(charBuffer, len));
                }
                if (ch == '\\')
                {
                    ch = UnEscape();
                }
                else if (ch < ' ')
                {
                    throw JsonParserException.UnexpectedError(ch, _position);
                }
                if (len >= StringInitialCapacity)
                {
                    _stringBuffer.Append(charBuffer, len);
                    len = 0;
                }
                charBuffer[len++] = ch;
                Consume();
            }
        }
Exemple #2
0
        private string GetString()
        {
            Consume();
            var start = _position;
            var len   = 0;

            while (true)
            {
                if (_isEnd)
                {
                    throw JsonParserException.UnexpectedEnd(start + len);
                }
                var ch = _nextChar;
                if (ch == '"')
                {
                    Consume();
                    return(new string(_charBuffer, 0, len));
                }
                if (ch == '\\')
                {
                    ch = UnEscape();
                }
                else if (ch < ' ')
                {
                    throw JsonParserException.UnexpectedError(ch, _position);
                }
                if (len >= _charBuffer.Length)
                {
                    Array.Resize(ref _charBuffer, _charBuffer.Length * 2);
                }
                _charBuffer[len++] = ch;
                Consume();
            }
        }
Exemple #3
0
        private unsafe object ParseInternal(TextReader reader, int maxDepth)
        {
            Setup(reader);
            var context    = new Context();
            var charBuffer = stackalloc char[StringInitialCapacity];

            SkipWhiteSpaces();
            while (true)
            {
                var value = new InternalObject();
                switch (_nextChar)
                {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                case '-':
                    value.Number = GetNumber();
                    break;

                case 'n':
                    CheckToken("ull");
                    value.Type = JsonType.Null;
                    break;

                case 't':
                    CheckToken("rue");
                    value.Type = JsonType.True;
                    break;

                case 'f':
                    // ReSharper disable once StringLiteralTypo
                    CheckToken("alse");
                    value.Type = JsonType.False;
                    break;

                case '"':
                    value.Type   = JsonType.String;
                    value.String = GetString(charBuffer);
                    break;

                case '[':
                    if (_stack.Count == maxDepth)
                    {
                        throw JsonParserException.TooDeepNesting(_stack.Count, _position);
                    }
                    Consume();
                    _stack.Push(context);
                    context = new Context
                    {
                        Array = new JsonArray()
                    };
                    SkipWhiteSpaces();
                    continue;

                case ']':
                    if (context.Array == null)
                    {
                        throw JsonParserException.UnexpectedError(_nextChar, _position);
                    }
                    Consume();
                    value.Type  = JsonType.Array;
                    value.Array = context.Array;
                    context     = _stack.Pop();
                    break;

                case '{':
                    if (_stack.Count == maxDepth)
                    {
                        throw JsonParserException.TooDeepNesting(_stack.Count, _position);
                    }
                    Consume();
                    _stack.Push(context);
                    context = new Context
                    {
                        Dictionary = new JsonDictionary()
                    };
                    goto GetKey;

                case '}':
                    if (context.Dictionary == null)
                    {
                        throw JsonParserException.UnexpectedError(_nextChar, _position);
                    }
                    Consume();
                    value.Type       = JsonType.Object;
                    value.Dictionary = context.Dictionary;
                    context          = _stack.Pop();
                    break;

                default:
                    if (_isEnd)
                    {
                        throw JsonParserException.UnexpectedEnd(_position);
                    }
                    throw JsonParserException.UnexpectedError(_nextChar, _position);
                }

                SkipWhiteSpaces();
                // Start
                if (_stack.Count == 0)
                {
                    // The buffer intentionally leaks in exceptional cases to simplify the code for exceptions.
                    BufferPool.Return(_buffer);
                    if (_isEnd)
                    {
                        return(JsonObject.ToValue(value));
                    }
                    throw JsonParserException.UnexpectedError(_nextChar, _position);
                }
                // Array
                if (context.Key == null)
                {
                    context.Array.Add(value);
                    if (_nextChar == ']')
                    {
                        continue;
                    }
                    if (_nextChar != ',')
                    {
                        throw JsonParserException.ExpectingError("',' or ']'", _position);
                    }
                    Consume();
                    SkipWhiteSpaces();
                    continue;
                }
                // Object
                context.Dictionary.Add(context.Key, value);
                if (_nextChar == '}')
                {
                    continue;
                }
                if (_nextChar != ',')
                {
                    throw JsonParserException.ExpectingError("',' or '}'", _position);
                }
                Consume();

GetKey:
                SkipWhiteSpaces();
                if (_nextChar == '}')
                {
                    continue;
                }
                if (_nextChar != '"')
                {
                    throw JsonParserException.ExpectingError("string", _position);
                }
                context.Key = GetString(charBuffer);
                SkipWhiteSpaces();
                if (_nextChar != ':')
                {
                    throw JsonParserException.ExpectingError("':'", _position);
                }
                Consume();
                SkipWhiteSpaces();
            }
        }
Exemple #4
0
        private object ParseInternal(TextReader reader, int maxDepth)
        {
            Setup(reader);
            var stack   = new Context[maxDepth];
            var depth   = 0;
            var context = new Context();

            SkipWhiteSpaces();
            while (true)
            {
                var value = new InternalObject();
                switch (_nextChar)
                {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                case '-':
                    value.Number = GetNumber();
                    break;

                case 'n':
                    CheckToken("ull");
                    value.Type = JsonType.Null;
                    break;

                case 't':
                    CheckToken("rue");
                    value.Type = JsonType.True;
                    break;

                case 'f':
                    // ReSharper disable once StringLiteralTypo
                    CheckToken("alse");
                    value.Type = JsonType.False;
                    break;

                case '"':
                    value.Type   = JsonType.String;
                    value.String = GetString();
                    break;

                case '[':
                    if (depth == maxDepth)
                    {
                        throw JsonParserException.TooDeepNesting(depth, _position);
                    }
                    Consume();
                    stack[depth++] = context;
                    context        = new Context
                    {
                        Array = new JsonArray()
                    };
                    SkipWhiteSpaces();
                    continue;

                case ']':
                    if (context.Array == null)
                    {
                        throw JsonParserException.UnexpectedError(_nextChar, _position);
                    }
                    Consume();
                    value.Type  = JsonType.Array;
                    value.Array = context.Array;
                    context     = stack[--depth];
                    break;

                case '{':
                    if (depth == maxDepth)
                    {
                        throw JsonParserException.TooDeepNesting(depth, _position);
                    }
                    Consume();
                    stack[depth++] = context;
                    context        = new Context
                    {
                        Dictionary = new JsonDictionary()
                    };
                    goto GetKey;

                case '}':
                    if (context.Dictionary == null)
                    {
                        throw JsonParserException.UnexpectedError(_nextChar, _position);
                    }
                    Consume();
                    value.Type       = JsonType.Object;
                    value.Dictionary = context.Dictionary;
                    context          = stack[--depth];
                    break;

                default:
                    if (_isEnd)
                    {
                        throw JsonParserException.UnexpectedEnd(_position);
                    }
                    throw JsonParserException.UnexpectedError(_nextChar, _position);
                }

                SkipWhiteSpaces();
                // Start
                if (depth == 0)
                {
                    if (_isEnd)
                    {
                        return(JsonObject.ToValue(value));
                    }
                    throw JsonParserException.UnexpectedError(_nextChar, _position);
                }
                // Array
                if (context.Key == null)
                {
                    context.Array.Add(value);
                    if (_nextChar == ']')
                    {
                        continue;
                    }
                    if (_nextChar != ',')
                    {
                        throw JsonParserException.ExpectingError("',' or ']'", _position);
                    }
                    Consume();
                    SkipWhiteSpaces();
                    continue;
                }
                // Object
                context.Dictionary.Add(context.Key, value);
                if (_nextChar == '}')
                {
                    continue;
                }
                if (_nextChar != ',')
                {
                    throw JsonParserException.ExpectingError("',' or '}'", _position);
                }
                Consume();

GetKey:
                SkipWhiteSpaces();
                if (_nextChar == '}')
                {
                    continue;
                }
                if (_nextChar != '"')
                {
                    throw JsonParserException.ExpectingError("string", _position);
                }
                context.Key = GetString();
                SkipWhiteSpaces();
                if (_nextChar != ':')
                {
                    throw JsonParserException.ExpectingError("':'", _position);
                }
                Consume();
                SkipWhiteSpaces();
            }
        }