ObjectDefaultConverter<T>
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace System.Text.Json.Serialization.Converters
{
internal 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)
{
object obj;
if (state.UseFastPath) {
if (reader.TokenType != JsonTokenType.StartObject)
ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
if (state.Current.JsonClassInfo.CreateObject == null)
ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(state.Current.JsonClassInfo.Type, ref reader, ref state);
obj = state.Current.JsonClassInfo.CreateObject();
while (true) {
ref reader.ReadWithVerify();
JsonTokenType tokenType = reader.TokenType;
if (tokenType == JsonTokenType.EndObject)
break;
ReadOnlySpan<byte> propertyName = JsonSerializer.GetPropertyName(ref state, ref reader, options);
bool useExtensionProperty;
JsonPropertyInfo jsonPropertyInfo = JsonSerializer.LookupProperty(obj, propertyName, ref state, out useExtensionProperty, true);
ReadPropertyValue(obj, ref state, ref reader, jsonPropertyInfo, useExtensionProperty);
}
} 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 < 14 && options.ReferenceHandler != null) {
if (!JsonSerializer.ResolveMetadataForJsonObject<T>(ref reader, ref state, options)) {
value = default(T);
return false;
}
if (state.Current.ObjectState == StackFrameObjectState.ReadRefEndObject) {
value = (T)state.Current.ReturnValue;
return true;
}
}
if ((int)state.Current.ObjectState < 15) {
if (state.Current.JsonClassInfo.CreateObject == null)
ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(state.Current.JsonClassInfo.Type, ref reader, ref state);
obj = state.Current.JsonClassInfo.CreateObject();
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;
JsonTokenType tokenType2 = reader.TokenType;
if (tokenType2 == JsonTokenType.EndObject)
break;
ReadOnlySpan<byte> propertyName2 = JsonSerializer.GetPropertyName(ref state, ref reader, options);
jsonPropertyInfo2 = JsonSerializer.LookupProperty(obj, propertyName2, ref state, out bool useExtensionProperty2, true);
state.Current.UseExtensionProperty = useExtensionProperty2;
} else
jsonPropertyInfo2 = state.Current.JsonPropertyInfo;
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;
}
if (!ReadAheadPropertyValue(ref state, ref reader, jsonPropertyInfo2)) {
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 sealed override bool OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, ref WriteStack state)
{
object obj = value;
if (!state.SupportContinuation) {
writer.WriteStartObject();
if (options.ReferenceHandler != null && 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;
state.Current.NumberHandling = jsonPropertyInfo.NumberHandling;
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) {
writer.WriteStartObject();
if (options.ReferenceHandler != null && 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;
state.Current.NumberHandling = jsonPropertyInfo2.NumberHandling;
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;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void ReadPropertyValue(object obj, ref ReadStack state, ref Utf8JsonReader reader, JsonPropertyInfo jsonPropertyInfo, bool useExtensionProperty)
{
if (!jsonPropertyInfo.ShouldDeserialize)
reader.Skip();
else {
ref reader.ReadWithVerify();
if (!useExtensionProperty)
jsonPropertyInfo.ReadJsonAndSetMember(obj, ref state, ref reader);
else
jsonPropertyInfo.ReadJsonAndAddExtensionProperty(obj, ref state, ref reader);
}
state.Current.EndProperty();
}
protected bool ReadAheadPropertyValue(ref ReadStack state, ref Utf8JsonReader reader, JsonPropertyInfo jsonPropertyInfo)
{
state.Current.PropertyState = StackFramePropertyState.ReadValue;
if (!state.Current.UseExtensionProperty) {
if (!JsonConverter.SingleValueReadWithReadAhead(jsonPropertyInfo.ConverterBase.ClassType, ref reader, ref state))
return false;
} else if (!JsonConverter.SingleValueReadWithReadAhead(ClassType.Value, ref reader, ref state)) {
return false;
}
return true;
}
internal sealed override void CreateInstanceForReferenceResolver(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options)
{
if (state.Current.JsonClassInfo.CreateObject == null)
ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(state.Current.JsonClassInfo.Type, ref reader, ref state);
object returnValue = state.Current.JsonClassInfo.CreateObject();
state.Current.ReturnValue = returnValue;
}
}
}