ObjectDefaultConverter<T>
using System.Diagnostics.CodeAnalysis;
namespace System.Text.Json.Serialization.Converters
{
internal sealed class ObjectDefaultConverter<T> : JsonObjectConverter<T>
{
internal override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out T value)
{
bool flag = options.ReferenceHandling.ShouldReadPreservedReferences();
object obj;
if (!state.SupportContinuation && !flag) {
if (reader.TokenType != JsonTokenType.StartObject)
ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
if (state.Current.JsonClassInfo.CreateObject == null)
ThrowHelper.ThrowNotSupportedException_DeserializeNoParameterlessConstructor(state.Current.JsonClassInfo.Type);
obj = state.Current.JsonClassInfo.CreateObject();
while (true) {
ref reader.ReadWithVerify();
switch (reader.TokenType) {
default:
ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
goto case JsonTokenType.PropertyName;
case JsonTokenType.PropertyName: {
bool useExtensionProperty;
JsonPropertyInfo jsonPropertyInfo = JsonSerializer.LookupProperty(obj, ref reader, options, ref state, out useExtensionProperty);
if (!jsonPropertyInfo.ShouldDeserialize) {
reader.Skip();
state.Current.EndProperty();
} else {
ref reader.ReadWithVerify();
if (!useExtensionProperty)
jsonPropertyInfo.ReadJsonAndSetMember(obj, ref state, ref reader);
else
jsonPropertyInfo.ReadJsonAndAddExtensionProperty(obj, ref state, ref reader);
state.Current.EndProperty();
}
continue;
}
case JsonTokenType.EndObject:
break;
}
break;
}
} else {
if (state.Current.ObjectState == StackFrameObjectState.None) {
if (reader.TokenType != JsonTokenType.StartObject)
ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
state.Current.ObjectState = StackFrameObjectState.StartToken;
}
if ((int)state.Current.ObjectState < 8) {
if (flag) {
if (!JsonSerializer.ResolveMetadata(this, ref reader, ref state)) {
value = default(T);
return false;
}
if (state.Current.ObjectState == StackFrameObjectState.MetadataRefPropertyEndObject) {
value = (T)state.Current.ReturnValue;
return true;
}
}
state.Current.ObjectState = StackFrameObjectState.MetadataPropertyValue;
}
if ((int)state.Current.ObjectState < 9) {
if (state.Current.JsonClassInfo.CreateObject == null)
ThrowHelper.ThrowNotSupportedException_DeserializeNoParameterlessConstructor(state.Current.JsonClassInfo.Type);
obj = state.Current.JsonClassInfo.CreateObject();
if (state.Current.MetadataId != null && !state.ReferenceResolver.AddReferenceOnDeserialize(state.Current.MetadataId, obj))
ThrowHelper.ThrowJsonException_MetadataDuplicateIdFound(state.Current.MetadataId, ref state);
state.Current.ReturnValue = obj;
state.Current.ObjectState = StackFrameObjectState.CreatedObject;
} else
obj = state.Current.ReturnValue;
while (true) {
if (state.Current.PropertyState == StackFramePropertyState.None) {
state.Current.PropertyState = StackFramePropertyState.ReadName;
if (!reader.Read()) {
state.Current.ReturnValue = obj;
value = default(T);
return false;
}
}
JsonPropertyInfo jsonPropertyInfo2;
if ((int)state.Current.PropertyState < 2) {
state.Current.PropertyState = StackFramePropertyState.Name;
switch (reader.TokenType) {
default:
ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
goto case JsonTokenType.PropertyName;
case JsonTokenType.PropertyName:
jsonPropertyInfo2 = JsonSerializer.LookupProperty(obj, ref reader, options, ref state, out bool useExtensionProperty2);
state.Current.UseExtensionProperty = useExtensionProperty2;
goto IL_02d5;
case JsonTokenType.EndObject:
break;
}
break;
}
jsonPropertyInfo2 = state.Current.JsonPropertyInfo;
goto IL_02d5;
IL_02d5:
if ((int)state.Current.PropertyState < 3) {
if (!jsonPropertyInfo2.ShouldDeserialize) {
if (!reader.TrySkip()) {
state.Current.ReturnValue = obj;
value = default(T);
return false;
}
state.Current.EndProperty();
continue;
}
state.Current.PropertyState = StackFramePropertyState.ReadValue;
if (!state.Current.UseExtensionProperty) {
if (!JsonConverter.SingleValueReadWithReadAhead(jsonPropertyInfo2.ConverterBase.ClassType, ref reader, ref state)) {
state.Current.ReturnValue = obj;
value = default(T);
return false;
}
} else if (!JsonConverter.SingleValueReadWithReadAhead(ClassType.Value, ref reader, ref state)) {
state.Current.ReturnValue = obj;
value = default(T);
return false;
}
}
if ((int)state.Current.PropertyState < 5) {
if (!state.Current.UseExtensionProperty) {
if (!jsonPropertyInfo2.ReadJsonAndSetMember(obj, ref state, ref reader)) {
state.Current.ReturnValue = obj;
value = default(T);
return false;
}
} else if (!jsonPropertyInfo2.ReadJsonAndAddExtensionProperty(obj, ref state, ref reader)) {
state.Current.ReturnValue = obj;
value = default(T);
return false;
}
state.Current.EndProperty();
}
}
}
if (state.Current.PropertyRefCache != null)
state.Current.JsonClassInfo.UpdateSortedPropertyCache(ref state.Current);
value = (T)obj;
return true;
}
internal override bool OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, ref WriteStack state)
{
object obj = value;
if (!state.SupportContinuation) {
if (obj == null) {
writer.WriteNullValue();
return true;
}
writer.WriteStartObject();
if (options.ReferenceHandling.ShouldWritePreservedReferences() && JsonSerializer.WriteReferenceForObject(this, obj, ref state, writer) == MetadataPropertyName.Ref)
return true;
JsonPropertyInfo dataExtensionProperty = state.Current.JsonClassInfo.DataExtensionProperty;
int num = 0;
JsonPropertyInfo[] propertyCacheArray = state.Current.JsonClassInfo.PropertyCacheArray;
if (propertyCacheArray != null)
num = propertyCacheArray.Length;
for (int i = 0; i < num; i++) {
JsonPropertyInfo jsonPropertyInfo = propertyCacheArray[i];
state.Current.DeclaredJsonPropertyInfo = jsonPropertyInfo;
if (jsonPropertyInfo.ShouldSerialize) {
if (jsonPropertyInfo == dataExtensionProperty) {
if (!jsonPropertyInfo.GetMemberAndWriteJsonExtensionData(obj, ref state, writer))
return false;
} else if (!jsonPropertyInfo.GetMemberAndWriteJson(obj, ref state, writer)) {
return false;
}
}
state.Current.EndProperty();
}
writer.WriteEndObject();
return true;
}
if (!state.Current.ProcessedStartToken) {
if (obj == null) {
writer.WriteNullValue();
return true;
}
writer.WriteStartObject();
if (options.ReferenceHandling.ShouldWritePreservedReferences() && JsonSerializer.WriteReferenceForObject(this, obj, ref state, writer) == MetadataPropertyName.Ref)
return true;
state.Current.ProcessedStartToken = true;
}
JsonPropertyInfo dataExtensionProperty2 = state.Current.JsonClassInfo.DataExtensionProperty;
int num2 = 0;
JsonPropertyInfo[] propertyCacheArray2 = state.Current.JsonClassInfo.PropertyCacheArray;
if (propertyCacheArray2 != null)
num2 = propertyCacheArray2.Length;
while (num2 > state.Current.EnumeratorIndex) {
JsonPropertyInfo jsonPropertyInfo2 = propertyCacheArray2[state.Current.EnumeratorIndex];
state.Current.DeclaredJsonPropertyInfo = jsonPropertyInfo2;
if (jsonPropertyInfo2.ShouldSerialize) {
if (jsonPropertyInfo2 == dataExtensionProperty2) {
if (!jsonPropertyInfo2.GetMemberAndWriteJsonExtensionData(obj, ref state, writer))
return false;
} else if (!jsonPropertyInfo2.GetMemberAndWriteJson(obj, ref state, writer)) {
return false;
}
}
state.Current.EndProperty();
state.Current.EnumeratorIndex++;
if (ShouldFlush(writer, ref state))
return false;
}
if (!state.Current.ProcessedEndToken) {
state.Current.ProcessedEndToken = true;
writer.WriteEndObject();
}
return true;
}
}
}