/// <summary> /// Parses out a JSON property AST node with a jsonTextReader. /// </summary> /// <param name="jsonTextReader">The reader to use as a lexer / tokenizer</param> /// <returns>JSON property AST node</returns> private static ObjectProperty ParsePropertyNode(IJsonTextReaderPrivateImplementation jsonTextReader) { ReadOnlyMemory <byte> bufferedRawJsonToken = jsonTextReader.GetBufferedJsonToken().Memory; FieldNameNode fieldName = FieldNameNode.Create(Utf8Memory.UnsafeCreateNoValidation(bufferedRawJsonToken)); // Consume the fieldname from the jsonreader jsonTextReader.Read(); JsonTextNavigatorNode value = Parser.ParseNode(jsonTextReader); return(new ObjectProperty(fieldName, value)); }
/// <summary> /// Initializes a new instance of the <see cref="JsonTextNavigator"/> class. /// </summary> /// <param name="buffer">The (UTF-8) buffer to navigate.</param> public JsonTextNavigator(ReadOnlyMemory <byte> buffer) { if (buffer.IsEmpty) { throw new ArgumentOutOfRangeException($"{nameof(buffer)} can not be empty."); } byte firstByte = buffer.Span[0]; byte lastByte = buffer.Span[buffer.Span.Length - 1]; bool objectRoot = (firstByte == '{') && (lastByte == '}'); bool arrayRoot = (firstByte == '[') && (lastByte == ']'); bool lazyInit = objectRoot || arrayRoot; JsonTextNavigatorNode CreateRootNode() { IJsonReader jsonTextReader = JsonReader.Create( buffer: buffer, jsonStringDictionary: null); if (jsonTextReader.SerializationFormat != JsonSerializationFormat.Text) { throw new InvalidOperationException($"{jsonTextReader}'s serialization format must actually be {JsonSerializationFormat.Text}."); } return(Parser.Parse(jsonTextReader)); } JsonTextNavigatorNode rootNode; if (lazyInit) { Lazy <JsonTextNavigatorNode> lazyNode = new Lazy <JsonTextNavigatorNode>(CreateRootNode); if (arrayRoot) { rootNode = new LazyArrayNode(lazyNode, buffer); } else { rootNode = new LazyObjectNode(lazyNode, buffer); } } else { rootNode = CreateRootNode(); } this.rootNode = rootNode; }
/// <summary> /// Initializes a new instance of the <see cref="JsonTextNavigator"/> class. /// </summary> /// <param name="buffer">The (UTF-8) buffer to navigate.</param> public JsonTextNavigator(ReadOnlyMemory <byte> buffer) { if (buffer.IsEmpty) { throw new ArgumentOutOfRangeException($"{nameof(buffer)} can not be empty."); } byte firstByte = buffer.Span[0]; byte lastByte = buffer.Span[buffer.Span.Length - 1]; bool objectRoot = (firstByte == '{') && (lastByte == '}'); bool arrayRoot = (firstByte == '[') && (lastByte == ']'); bool lazyInit = objectRoot || arrayRoot; JsonTextNavigatorNode CreateRootNode() { IJsonReader jsonTextReader = JsonReader.Create( buffer: buffer, jsonStringDictionary: null); if (!(jsonTextReader is IJsonTextReaderPrivateImplementation jsonTextReaderExtensions)) { throw new InvalidOperationException($"{nameof(jsonTextReader)} needs to implement {nameof(IJsonTextReaderPrivateImplementation)}."); } return(Parser.Parse(jsonTextReaderExtensions)); } JsonTextNavigatorNode rootNode; if (lazyInit) { Lazy <JsonTextNavigatorNode> lazyNode = new Lazy <JsonTextNavigatorNode>(CreateRootNode); if (arrayRoot) { rootNode = new LazyArrayNode(lazyNode, buffer); } else { rootNode = new LazyObjectNode(lazyNode, buffer); } } else { rootNode = CreateRootNode(); } this.rootNode = rootNode; }
/// <summary> /// Parses out a JSON property AST node with a jsonTextReader. /// </summary> /// <param name="jsonTextReader">The reader to use as a lexer / tokenizer</param> /// <returns>JSON property AST node</returns> private static ObjectProperty ParsePropertyNode(IJsonReader jsonTextReader) { if (!jsonTextReader.TryGetBufferedRawJsonToken(out ReadOnlyMemory <byte> bufferedRawJsonToken)) { throw new InvalidOperationException("Failed to get the buffered raw json token."); } FieldNameNode fieldName = FieldNameNode.Create(Utf8Memory.UnsafeCreateNoValidation(bufferedRawJsonToken)); // Consume the fieldname from the jsonreader jsonTextReader.Read(); JsonTextNavigatorNode value = Parser.ParseNode(jsonTextReader); return(new ObjectProperty(fieldName, value)); }
/// <summary> /// Gets the root node of a JSON AST from a jsonTextReader. /// </summary> /// <param name="jsonTextReader">The reader to use as a lexer / tokenizer</param> /// <returns>The root node of a JSON AST from a jsonTextReader.</returns> public static JsonTextNavigatorNode Parse(IJsonTextReaderPrivateImplementation jsonTextReader) { // Read past the json object not started state. if (!jsonTextReader.Read()) { throw new InvalidOperationException("Failed to read from reader"); } JsonTextNavigatorNode rootNode = Parser.ParseNode(jsonTextReader); // Make sure that we are at the end of the file. if (jsonTextReader.Read()) { throw new ArgumentException("Did not fully parse json"); } return(rootNode); }
private static ReadOnlyMemory <byte> GetNodeBuffer(JsonTextNavigatorNode jsonTextNavigatorNode) { return(jsonTextNavigatorNode switch { LazyNode lazyNode => lazyNode.BufferedValue, ArrayNode arrayNode => arrayNode.BufferedValue, FalseNode falseNode => SingletonBuffers.False, StringNodeBase stringNodeBase => stringNodeBase.BufferedValue.Memory, NullNode nullNode => SingletonBuffers.Null, NumberNode numberNode => numberNode.BufferedToken, ObjectNode objectNode => objectNode.BufferedValue, TrueNode trueNode => SingletonBuffers.True, GuidNode guidNode => guidNode.BufferedToken, BinaryNode binaryNode => binaryNode.BufferedToken, IntegerNode intNode => intNode.BufferedToken, FloatNode floatNode => floatNode.BufferedToken, _ => throw new ArgumentOutOfRangeException($"Unknown {nameof(JsonTextNavigatorNode)} type: {jsonTextNavigatorNode.GetType()}."), });
/// <summary> /// Gets the root node of a JSON AST from a jsonTextReader. /// </summary> /// <param name="jsonTextReader">The reader to use as a lexer / tokenizer</param> /// <returns>The root node of a JSON AST from a jsonTextReader.</returns> public static JsonTextNavigatorNode Parse(IJsonReader jsonTextReader) { if (jsonTextReader.SerializationFormat != JsonSerializationFormat.Text) { throw new ArgumentException("jsonTextReader's serialization format must actually be text"); } // Read past the json object not started state. if (!jsonTextReader.Read()) { throw new InvalidOperationException("Failed to read from reader"); } JsonTextNavigatorNode rootNode = Parser.ParseNode(jsonTextReader); // Make sure that we are at the end of the file. if (jsonTextReader.Read()) { throw new ArgumentException("Did not fully parse json"); } return(rootNode); }
private static ReadOnlyMemory <byte> GetNodeBuffer(JsonTextNavigatorNode jsonTextNavigatorNode) => jsonTextNavigatorNode switch {