/// <summary> /// Asynchronously called whenever we find a new object value in the payload. /// Buffers and re-orders an object value for later consumption by the JsonLight reader. /// </summary> /// <remarks> /// This method is called when the reader is in the buffering mode and can read ahead (buffering) as much as it needs to /// once it returns the reader will be returned to the position before the method was called. /// The reader is always positioned on a start object when this method is called. /// </remarks> protected override async Task ProcessObjectValueAsync() { Debug.Assert(this.currentBufferedNode.NodeType == JsonNodeType.StartObject, "this.currentBufferedNode.NodeType == JsonNodeType.StartObject"); this.AssertBuffering(); Stack <BufferedObject> bufferedObjectStack = new Stack <BufferedObject>(); while (true) { switch (this.currentBufferedNode.NodeType) { case JsonNodeType.StartObject: { // New object record - add the node to our stack BufferedObject bufferedObject = new BufferedObject { ObjectStart = this.currentBufferedNode }; bufferedObjectStack.Push(bufferedObject); // See if it's an in-stream error await base.ProcessObjectValueAsync() .ConfigureAwait(false); this.currentBufferedNode = bufferedObject.ObjectStart; await this.ReadInternalAsync() .ConfigureAwait(false); } break; case JsonNodeType.EndObject: { // End of object record // Pop the node from our stack BufferedObject bufferedObject = bufferedObjectStack.Pop(); // If there is a previous property record, mark its last value node. if (bufferedObject.CurrentProperty != null) { bufferedObject.CurrentProperty.EndOfPropertyValueNode = this.currentBufferedNode.Previous; } // Now perform the re-ordering on the buffered nodes bufferedObject.Reorder(); if (bufferedObjectStack.Count == 0) { // No more objects to process - we're done. return; } await this.ReadInternalAsync() .ConfigureAwait(false); } break; case JsonNodeType.Property: { BufferedObject bufferedObject = bufferedObjectStack.Peek(); // If there is a current property, mark its last value node. if (bufferedObject.CurrentProperty != null) { bufferedObject.CurrentProperty.EndOfPropertyValueNode = this.currentBufferedNode.Previous; } BufferedProperty bufferedProperty = new BufferedProperty(); bufferedProperty.PropertyNameNode = this.currentBufferedNode; string propertyName, annotationName; Tuple <string, string> readPropertyNameResult = await this.ReadPropertyNameAsync() .ConfigureAwait(false); propertyName = readPropertyNameResult.Item1; annotationName = readPropertyNameResult.Item2; bufferedProperty.PropertyAnnotationName = annotationName; bufferedObject.AddBufferedProperty(propertyName, annotationName, bufferedProperty); if (annotationName != null) { // Instance-level property annotation - no reordering in its value // or instance-level annotation - no reordering in its value either // So skip its value while buffering. await this.BufferValueAsync() .ConfigureAwait(false); } } break; default: // Read over (buffer) everything else await this.ReadInternalAsync() .ConfigureAwait(false); break; } } }
/// <summary> /// Called whenever we find a new object value in the payload. /// Buffers and re-orders an object value for later consumption by the JsonLight reader. /// </summary> /// <remarks> /// This method is called when the reader is in the buffering mode and can read ahead (buffering) as much as it needs to /// once it returns the reader will be returned to the position before the method was called. /// The reader is always positioned on a start object when this method is called. /// </remarks> protected override void ProcessObjectValue() { Debug.Assert(this.currentBufferedNode.NodeType == JsonNodeType.StartObject, "this.currentBufferedNode.NodeType == JsonNodeType.StartObject"); this.AssertBuffering(); Stack<BufferedObject> bufferedObjectStack = new Stack<BufferedObject>(); while (true) { switch (this.currentBufferedNode.NodeType) { case JsonNodeType.StartObject: { // New object record - add the node to our stack BufferedObject bufferedObject = new BufferedObject { ObjectStart = this.currentBufferedNode }; bufferedObjectStack.Push(bufferedObject); // See if it's an in-stream error base.ProcessObjectValue(); this.currentBufferedNode = bufferedObject.ObjectStart; this.ReadInternal(); } break; case JsonNodeType.EndObject: { // End of object record // Pop the node from our stack BufferedObject bufferedObject = bufferedObjectStack.Pop(); // If there is a previous property record, mark its last value node. if (bufferedObject.CurrentProperty != null) { bufferedObject.CurrentProperty.EndOfPropertyValueNode = this.currentBufferedNode.Previous; } // Now perform the re-ordering on the buffered nodes bufferedObject.Reorder(); if (bufferedObjectStack.Count == 0) { // No more objects to process - we're done. return; } this.ReadInternal(); } break; case JsonNodeType.Property: { BufferedObject bufferedObject = bufferedObjectStack.Peek(); // If there is a current property, mark its last value node. if (bufferedObject.CurrentProperty != null) { bufferedObject.CurrentProperty.EndOfPropertyValueNode = this.currentBufferedNode.Previous; } BufferedProperty bufferedProperty = new BufferedProperty(); bufferedProperty.PropertyNameNode = this.currentBufferedNode; string propertyName; string annotationName; this.ReadPropertyName(out propertyName, out annotationName); bufferedProperty.PropertyAnnotationName = annotationName; bufferedObject.AddBufferedProperty(propertyName, annotationName, bufferedProperty); if (annotationName != null) { // Instance-level property annotation - no reordering in its value // or instance-level annotation - no reordering in its value either // So skip its value while buffering. this.BufferValue(); } } break; default: // Read over (buffer) everything else this.ReadInternal(); break; } } }