ReadStack
struct ReadStack
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;
namespace System.Text.Json
{
[DebuggerDisplay("Path:{JsonPath()} Current: ClassType.{Current.JsonClassInfo.ClassType}, {Current.JsonClassInfo.Type.Name}")]
internal struct ReadStack
{
internal static readonly char[] SpecialCharacters = new char[18] {
'.',
' ',
'\'',
'/',
'"',
'[',
']',
'(',
')',
'\t',
'\n',
'\r',
'',
'\b',
'\\',
'
',
'
',
'
'
};
private int _continuationCount;
private int _count;
private List<ReadStackFrame> _previous;
private List<ArgumentState> _ctorArgStateCache;
public long BytesConsumed;
public ReadStackFrame Current;
public bool ReadAhead;
public ReferenceResolver ReferenceResolver;
public bool SupportContinuation;
public bool UseFastPath;
public bool IsContinuation => _continuationCount != 0;
public bool IsLastContinuation => _continuationCount == _count;
private void AddCurrent()
{
if (_previous == null)
_previous = new List<ReadStackFrame>();
if (_count > _previous.Count)
_previous.Add(Current);
else
_previous[_count - 1] = Current;
_count++;
}
public void Initialize(Type type, JsonSerializerOptions options, bool supportContinuation)
{
JsonClassInfo orAddClassForRootType = options.GetOrAddClassForRootType(type);
Current.JsonClassInfo = orAddClassForRootType;
Current.JsonPropertyInfo = orAddClassForRootType.PropertyInfoForClassInfo;
Current.NumberHandling = Current.JsonPropertyInfo.NumberHandling;
bool flag = options.ReferenceHandler != null;
if (flag)
ReferenceResolver = options.ReferenceHandler.CreateResolver(false);
SupportContinuation = supportContinuation;
UseFastPath = (!supportContinuation && !flag);
}
public void Push()
{
if (_continuationCount == 0) {
if (_count == 0)
_count = 1;
else {
JsonNumberHandling? numberHandling = Current.NumberHandling;
JsonClassInfo jsonClassInfo = (Current.JsonClassInfo.ClassType == ClassType.Object) ? ((Current.JsonPropertyInfo == null) ? Current.CtorArgumentState.JsonParameterInfo.RuntimeClassInfo : Current.JsonPropertyInfo.RuntimeClassInfo) : ((((ClassType)6 & Current.JsonClassInfo.ClassType) == ClassType.None) ? Current.JsonClassInfo.ElementClassInfo : Current.JsonPropertyInfo.RuntimeClassInfo);
AddCurrent();
Current.Reset();
Current.JsonClassInfo = jsonClassInfo;
Current.JsonPropertyInfo = jsonClassInfo.PropertyInfoForClassInfo;
Current.NumberHandling = (numberHandling ?? Current.JsonPropertyInfo.NumberHandling);
}
} else if (_continuationCount == 1) {
_continuationCount = 0;
} else {
Current = _previous[_count - 1];
if (_count == _continuationCount)
_continuationCount = 0;
else
_count++;
}
SetConstructorArgumentState();
}
public void Pop(bool success)
{
if (!success) {
if (_continuationCount == 0) {
if (_count == 1)
_continuationCount = 1;
else {
AddCurrent();
_count--;
_continuationCount = _count;
_count--;
Current = _previous[_count - 1];
}
return;
}
if (_continuationCount == 1)
return;
_previous[_count - 1] = Current;
}
if (_count > 1)
Current = _previous[--_count - 1];
SetConstructorArgumentState();
}
public string JsonPath()
{
StringBuilder stringBuilder = new StringBuilder("$");
int num = Math.Max(_count, _continuationCount);
for (int i = 0; i < num - 1; i++) {
StringBuilder sb = stringBuilder;
ReadStackFrame frame = _previous[i];
<JsonPath>g__AppendStackFrame|19_0(sb, ref frame);
}
if (_continuationCount == 0)
<JsonPath>g__AppendStackFrame|19_0(stringBuilder, ref Current);
return stringBuilder.ToString();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetConstructorArgumentState()
{
if (Current.JsonClassInfo.ParameterCount > 0) {
if (Current.CtorArgumentStateIndex == 0) {
if (_ctorArgStateCache == null)
_ctorArgStateCache = new List<ArgumentState>();
ArgumentState argumentState = new ArgumentState();
_ctorArgStateCache.Add(argumentState);
ref int ctorArgumentStateIndex = ref Current.CtorArgumentStateIndex;
ref ArgumentState ctorArgumentState = ref Current.CtorArgumentState;
int count = _ctorArgStateCache.Count;
ArgumentState argumentState2 = argumentState;
ctorArgumentStateIndex = count;
ctorArgumentState = argumentState2;
} else
Current.CtorArgumentState = _ctorArgStateCache[Current.CtorArgumentStateIndex - 1];
}
}
}
}