Ejemplo n.º 1
0
        public IJsonNode ReadValue(JsonLiteral literal)
        {
            switch (literal)
            {
            case JsonLiteral.Quote:
                return(new JsonString(ReadString(expectStartToken: false)));

            case JsonLiteral.Number:
                return(ReadNumber());

            case JsonLiteral.Null:
                return(JsonNull.Instance);

            case JsonLiteral.True:
                return(JsonBool.True);

            case JsonLiteral.False:
                return(JsonBool.False);

            case JsonLiteral.Undefined:
                return(JsonUndefined.Instance);

            default:
                throw UnexpectedJsonException.From("value token", _buffer, _encoding);
            }
        }
Ejemplo n.º 2
0
        private bool TryVisitNumber <T>(VisitArgs args, Func <decimal?, T> converter, out T value)
        {
            var node = ParseUntilFound(args);

            if (node is JsonUndefined)
            {
                value = default;
                return(false);
            }
            if (node.IsNull)
            {
                value = default;
                return(true);
            }

            if (node is JsonString str)
            {
                var parsedNumber = decimal.Parse(str.Value);
                value = converter.Invoke(parsedNumber);
                return(true);
            }
            if (!(node is JsonNumber number))
            {
                throw UnexpectedJsonException.Type(args.Name, node, typeof(T));
            }
            value = converter.Invoke(number.Value);
            return(true);
        }
Ejemplo n.º 3
0
        public bool ReadFieldValue(out IJsonNode node)
        {
            var literal = ReadLiteral();

            if (literal != JsonLiteral.Assignment)
            {
                throw UnexpectedJsonException.InObject(literal);
            }

            literal = ReadLiteral();
            switch (literal)
            {
            case JsonLiteral.ObjectBegin:
                node = ReadObject(expectStartToken: false);
                break;

            case JsonLiteral.ArrayBegin:
                node = ReadArray(expectStartToken: false);
                break;

            case JsonLiteral.Quote:
                var value = ReadString(expectStartToken: false);
                node = new JsonString(value);
                break;

            case JsonLiteral.Number:
                node = ReadNumber();
                break;

            case JsonLiteral.Null:
                node = JsonNull.Instance;
                break;

            case JsonLiteral.True:
                node = JsonBool.True;
                break;

            case JsonLiteral.False:
                node = JsonBool.False;
                break;

            case JsonLiteral.Undefined:
                node = JsonUndefined.Instance;
                break;

            default:
                throw UnexpectedJsonException.InObject(literal);
            }
            return(true);
        }
Ejemplo n.º 4
0
        public ValueState TryVisit(VisitArgs args)
        {
            if (args.IsRoot)
            {
                var literal = _reader.ReadLiteral();
                if (literal == JsonLiteral.Null)
                {
                    return(ValueState.Null);
                }
                switch (args.Type)
                {
                case LevelType.Dictionary:
                case LevelType.Single:
                    if (literal == JsonLiteral.ObjectBegin)
                    {
                        _parents.Push(new JsonReadLevel(new JsonObject()));
                        return(ValueState.Found);
                    }
                    throw UnexpectedJsonException.From("object begin token", _buffer, _encoding);

                case LevelType.Collection:
                    if (literal == JsonLiteral.ArrayBegin)
                    {
                        _parents.Push(ArrayLevel);
                        return(ValueState.Found);
                    }
                    throw UnexpectedJsonException.From("array begin token", _buffer, _encoding);
                }

                throw UnexpectedJsonException.From("root begin", _buffer, _encoding);
            }

            var node = ParseUntilFound(args);

            if (node == null)
            {
                return(ValueState.NotFound);
            }
            if (node.IsNull)
            {
                return(ValueState.Null);
            }
            return(ValueState.Found);
        }
Ejemplo n.º 5
0
        public bool ReadFieldName(out string name)
        {
            var literal = ReadLiteral();

            if (literal == JsonLiteral.Comma)
            {
                literal = ReadLiteral();
            }
            if (literal == JsonLiteral.ObjectEnd)
            {
                name = null;
                return(false);
            }
            if (literal != JsonLiteral.Quote)
            {
                throw UnexpectedJsonException.InObject(literal);
            }
            name = ReadString(expectStartToken: false);
            return(true);
        }
Ejemplo n.º 6
0
        public bool TryVisitValue(VisitArgs args, out bool?value)
        {
            var node = ParseUntilFound(args);

            if (node is JsonUndefined)
            {
                value = null;
                return(false);
            }
            if (node.IsNull)
            {
                value = null;
                return(true);
            }
            if (!(node is JsonBool b))
            {
                throw UnexpectedJsonException.Type(args.Name, node, typeof(bool));
            }
            value = b.Value;
            return(true);
        }
Ejemplo n.º 7
0
        private bool TryVisitString <T>(VisitArgs args, Func <string, T> converter, out T value)
        {
            var node = ParseUntilFound(args);

            if (node is JsonUndefined)
            {
                value = default(T);
                return(false);
            }
            if (node.IsNull)
            {
                value = default(T);
                return(true);
            }
            if (!(node is JsonString s))
            {
                throw UnexpectedJsonException.Type(args.Name, node, typeof(T));
            }
            value = converter.Invoke(s.Value);
            return(true);
        }
Ejemplo n.º 8
0
        private JsonLiteral ReadLiteral(bool advance)
        {
            var first = _buffer.PeekByte();

            while (IsLiteral(first, _encoding.Space, advance: true) ||
                   IsLiteral(first, _encoding.CarriageReturn, advance: true) ||
                   IsLiteral(first, _encoding.Newline, advance: true) ||
                   IsLiteral(first, _encoding.HorizontalTab, advance: true))
            {
                first = _buffer.PeekByte();
            }

            if (IsLiteral(first, _encoding.ObjectBegin, advance))
            {
                return(JsonLiteral.ObjectBegin);
            }
            if (IsLiteral(first, _encoding.ObjectEnd, advance))
            {
                return(JsonLiteral.ObjectEnd);
            }
            if (IsLiteral(first, _encoding.ArrayBegin, advance))
            {
                return(JsonLiteral.ArrayBegin);
            }
            if (IsLiteral(first, _encoding.ArrayEnd, advance))
            {
                return(JsonLiteral.ArrayEnd);
            }
            if (IsLiteral(first, _encoding.Assignment, advance))
            {
                return(JsonLiteral.Assignment);
            }
            if (IsLiteral(first, _encoding.Quote, advance))
            {
                return(JsonLiteral.Quote);
            }
            if (IsLiteral(first, _encoding.Comma, advance))
            {
                return(JsonLiteral.Comma);
            }
            if (IsLiteral(first, _encoding.Minus, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.Zero, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.One, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.Two, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.Three, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.Four, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.Five, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.Six, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.Seven, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.Eight, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.Nine, advance: false))
            {
                return(JsonLiteral.Number);
            }
            if (IsLiteral(first, _encoding.Null, advance))
            {
                return(JsonLiteral.Null);
            }
            if (IsLiteral(first, _encoding.True, advance))
            {
                return(JsonLiteral.True);
            }
            if (IsLiteral(first, _encoding.False, advance))
            {
                return(JsonLiteral.False);
            }
            if (IsLiteral(first, _encoding.Undefined, advance))
            {
                return(JsonLiteral.Undefined);
            }
            throw UnexpectedJsonException.From("literal or value", _buffer, _encoding);
        }
Ejemplo n.º 9
0
        private JsonArray ReadArray(bool expectStartToken)
        {
            var arr = new JsonArray();

            var literal = ReadLiteral();

            if (expectStartToken && literal != JsonLiteral.ArrayBegin)
            {
                throw UnexpectedJsonException.InArray(literal);
            }

            while (literal != JsonLiteral.ArrayEnd)
            {
                switch (literal)
                {
                case JsonLiteral.ObjectBegin:
                    var obj = ReadObject(expectStartToken: false);
                    arr.Add(obj);
                    continue;

                case JsonLiteral.ArrayBegin:
                    var arrInArr = ReadArray(expectStartToken: false);
                    arr.Add(arrInArr);
                    continue;

                case JsonLiteral.Quote:
                    var value = ReadString(expectStartToken: false);
                    arr.Add(new JsonString(value));
                    continue;

                case JsonLiteral.Number:
                    break;

                case JsonLiteral.Null:
                    break;

                case JsonLiteral.True:
                    break;

                case JsonLiteral.False:
                    break;

                case JsonLiteral.Undefined:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                literal = ReadLiteral();
                if (literal == JsonLiteral.Comma)
                {
                    literal = ReadLiteral();
                    if (literal == JsonLiteral.ArrayEnd)
                    {
                        throw UnexpectedJsonException.InArray(JsonLiteral.Comma);
                    }
                }
                else if (literal != JsonLiteral.ArrayEnd)
                {
                    throw UnexpectedJsonException.InArray(literal);
                }
            }

            return(arr);
        }
Ejemplo n.º 10
0
        private string ReadString(bool expectStartToken)
        {
            if (expectStartToken)
            {
                if (IsNextCharacter(_encoding.Quote, _buffer.Position))
                {
                    _buffer.Advance(_encoding.Quote.Length);
                }
                else
                {
                    throw UnexpectedJsonException.From("\"", _buffer, _encoding);
                }
            }

            var b      = new StringBuilder();
            var offset = _buffer.Position;

            do
            {
                if ((_buffer.Length - offset) < _encoding.BinaryFormat.MaxSize * 2)
                {
                    AppendString(b, offset);
                    _buffer.RequestSpace(_encoding.BinaryFormat.MaxSize * 2);
                    offset = _buffer.Position;
                }
                if (IsNextCharacter(_encoding.Quote, offset))
                {
                    AppendString(b, offset);
                    _buffer.Advance(_encoding.Quote.Length);
                    return(b.ToString());
                }
                if (IsNextCharacter(_encoding.ReverseSolidus, offset))
                {
                    AppendString(b, offset);
                    offset += _encoding.ReverseSolidus.Length;
                    if (IsNextCharacter(_encoding.Backspace, offset))
                    {
                        b.Append('\b');
                    }
                    else if (IsNextCharacter(_encoding.ReverseSolidus, offset))
                    {
                        b.Append('\\');
                    }
                    else if (IsNextCharacter(_encoding.Quote, offset))
                    {
                        b.Append('\"');
                    }
                    else if (IsNextCharacter(_encoding.CarriageReturn, offset))
                    {
                        b.Append('\r');
                    }
                    else if (IsNextCharacter(_encoding.Formfeed, offset))
                    {
                        b.Append('\f');
                    }
                    else if (IsNextCharacter(_encoding.HorizontalTab, offset))
                    {
                        b.Append('\t');
                    }
                    else if (IsNextCharacter(_encoding.Newline, offset))
                    {
                        b.Append('\n');
                    }
                    else if (IsNextCharacter(_encoding.Solidus, offset))
                    {
                        b.Append('/');
                    }
                    else
                    {
                        throw UnexpectedJsonException.From("escaped character.", _buffer, _encoding);
                    }
                }
                offset += _encoding.GetCharacterSize(_buffer.Buffer, offset);
            } while (true);
        }
Ejemplo n.º 11
0
        private IJsonNode ParseUntilFound(VisitArgs args)
        {
            var name = string.IsNullOrEmpty(args.Name)
                ? null
                : _fieldNameResolver.Resolve(args);

            JsonLiteral literal;

            if (args.IsRoot)
            {
                // When the value being deserialized is a simple value only
                literal = _reader.ReadLiteral();
                return(_reader.ReadValue(literal));
            }

            var parent = _parents.Peek();

            if (args.Type.IsDictionaryKey())
            {
                if (!_reader.ReadFieldName(out var key))
                {
                    parent.IsFullyParsed = true;
                    return(JsonUndefined.Instance);
                }
                return(new JsonString(key));
            }
            if (args.Type.IsDictionaryValue())
            {
                literal = _reader.ReadLiteral();
                if (literal != JsonLiteral.Assignment)
                {
                    throw UnexpectedJsonException.From("dictionary assignment token", _buffer, _encoding);
                }
                literal = _reader.ReadLiteral();
                if (literal == JsonLiteral.ObjectBegin)
                {
                    var child = new JsonObject();
                    _parents.Push(new JsonReadLevel(child));
                    return(child);
                }
                if (literal == JsonLiteral.ArrayBegin)
                {
                    _parents.Push(ArrayLevel);
                    return(ArrayLevel.Node);
                }
                return(_reader.ReadValue(literal));
            }

            if (parent.Node is JsonObject obj)
            {
                if (obj.TryGet(name, out var field))
                {
                    if (field is JsonObject || field is JsonArray)
                    {
                        _parents.Push(new JsonReadLevel(field));
                    }
                    return(field);
                }

                if (parent.IsFullyParsed)
                {
                    return(JsonUndefined.Instance);
                }

                while (true)
                {
                    if (!_reader.ReadFieldName(out var fieldName))
                    {
                        parent.IsFullyParsed = true;
                        return(JsonUndefined.Instance);
                    }

                    if (string.Equals(fieldName, name, StringComparison.Ordinal))
                    {
                        if (args.Type == LevelType.Single || args.Type.IsDictionary())
                        {
                            literal = _reader.ReadLiteral();
                            if (literal != JsonLiteral.Assignment)
                            {
                                throw UnexpectedJsonException.From("assignment token", _buffer, _encoding);
                            }
                            literal = _reader.ReadLiteral();
                            if (literal == JsonLiteral.Null)
                            {
                                return(JsonNull.Instance);
                            }
                            if (literal == JsonLiteral.ObjectBegin)
                            {
                                var child = new JsonObject();
                                _parents.Push(new JsonReadLevel(child));
                                return(child);
                            }
                            throw UnexpectedJsonException.From("object begin token", _buffer, _encoding);
                        }
                        if (args.Type.IsCollection())
                        {
                            literal = _reader.ReadLiteral();
                            if (literal != JsonLiteral.Assignment)
                            {
                                throw UnexpectedJsonException.From("assignment token", _buffer, _encoding);
                            }
                            literal = _reader.ReadLiteral();
                            if (literal == JsonLiteral.Null)
                            {
                                return(JsonNull.Instance);
                            }
                            if (literal == JsonLiteral.ArrayBegin)
                            {
                                _parents.Push(ArrayLevel);
                                return(ArrayLevel.Node);
                            }
                            throw UnexpectedJsonException.From("array begin token", _buffer, _encoding);
                        }
                        if (!_reader.ReadFieldValue(out var fieldValue))
                        {
                            throw UnexpectedJsonException.From("field value", _buffer, _encoding);
                        }
                        return(fieldValue);
                    }

                    if (!_reader.ReadFieldValue(out var fieldNode))
                    {
                        throw UnexpectedJsonException.From("field value", _buffer, _encoding);
                    }

                    obj.Add(fieldName, fieldNode);
                }
            }

            literal = _reader.ReadLiteral();
            if (literal == JsonLiteral.Comma)
            {
                literal = _reader.ReadLiteral();
            }

            if (args.Type == LevelType.Collection)
            {
                if (literal == JsonLiteral.ArrayBegin)
                {
                    _parents.Push(ArrayLevel);
                    return(ArrayLevel.Node);
                }
                throw UnexpectedJsonException.From("array begin token", _buffer, _encoding);
            }
            if (literal == JsonLiteral.ObjectBegin)
            {
                var child = new JsonObject();
                _parents.Push(new JsonReadLevel(child));
                return(child);
            }
            if (literal == JsonLiteral.ArrayEnd)
            {
                return(JsonUndefined.Instance);
            }

            return(_reader.ReadValue(literal));
        }