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