private static void HandleStartArray( JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state) { JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; if (state.Current.SkipProperty) { // The array is not being applied to the object. state.Push(); state.Current.Drain = true; return; } if (jsonPropertyInfo == null) { jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootObject(options); } else if (state.Current.JsonClassInfo.ClassType == ClassType.Unknown) { jsonPropertyInfo = state.Current.JsonClassInfo.CreatePolymorphicProperty(jsonPropertyInfo, typeof(object), options); } // Verify that we don't have a multidimensional array. Type arrayType = jsonPropertyInfo.RuntimePropertyType; if (!typeof(IEnumerable).IsAssignableFrom(arrayType) || (arrayType.IsArray && arrayType.GetArrayRank() > 1)) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(arrayType, reader, state.JsonPath); } Debug.Assert(state.Current.IsProcessingEnumerableOrDictionary); if (state.Current.CollectionPropertyInitialized) { // A nested json array so push a new stack frame. Type elementType = jsonPropertyInfo.ElementClassInfo.Type; state.Push(); state.Current.Initialize(elementType, options); } state.Current.CollectionPropertyInitialized = true; jsonPropertyInfo = state.Current.JsonPropertyInfo; if (state.Current.JsonClassInfo.ClassType == ClassType.Value) { state.Current.JsonPropertyInfo.Read(JsonTokenType.StartObject, ref state, ref reader); } else { // If current property is already set (from a constructor, for example) leave as-is. if (jsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue) == null) { // Create the enumerable. object value = ReadStackFrame.CreateEnumerableValue(ref reader, ref state, options); // If value is not null, then we don't have a converter so apply the value. if (value != null) { if (state.Current.ReturnValue != null) { state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value); } else { // Primitive arrays being returned without object state.Current.SetReturnValue(value); } } } } }
private static void HandleStartArray(JsonSerializerOptions options, ref ReadStack state) { if (state.Current.SkipProperty) { // The array is not being applied to the object. state.Push(); state.Current.Drain = true; return; } Debug.Assert(state.Current.JsonClassInfo != null); JsonPropertyInfo?jsonPropertyInfo = state.Current.JsonPropertyInfo; if (jsonPropertyInfo == null) { jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootProperty(options); } // Verify that we are processing a valid enumerable or dictionary. if (((ClassType.Enumerable | ClassType.Dictionary) & jsonPropertyInfo.ClassType) == 0) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(jsonPropertyInfo.RuntimePropertyType); } if (state.Current.CollectionPropertyInitialized) { // An array nested in a dictionary or array, so push a new stack frame. Type elementType = jsonPropertyInfo.ElementClassInfo !.Type; state.Push(); state.Current.Initialize(elementType, options); } state.Current.CollectionPropertyInitialized = true; // The current JsonPropertyInfo will be null if the current type is not one of // ClassType.Value | ClassType.Enumerable | ClassType.Dictionary. // We should not see ClassType.Value here because we handle it on a different code // path invoked in the main read loop. // Only ClassType.Enumerable is valid here since we just saw a StartArray token. if (state.Current.JsonPropertyInfo == null || state.Current.JsonPropertyInfo.ClassType != ClassType.Enumerable) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(state.Current.JsonClassInfo.Type); } // Set or replace the existing enumerable value. object?value = ReadStackFrame.CreateEnumerableValue(ref state); // If value is not null, then we don't have a converter so apply the value. if (value != null) { state.Current.DetermineEnumerablePopulationStrategy(value); if (state.Current.ReturnValue != null) { state.Current.JsonPropertyInfo !.SetValueAsObject(state.Current.ReturnValue, value); } else { state.Current.ReturnValue = value; } } }
private static void HandleStartArray( JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state) { if (state.Current.SkipProperty) { // The array is not being applied to the object. state.Push(); state.Current.Drain = true; return; } JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; if (jsonPropertyInfo == null) { jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootObject(options); } else if (state.Current.JsonClassInfo.ClassType == ClassType.Unknown) { jsonPropertyInfo = state.Current.JsonClassInfo.CreatePolymorphicProperty(jsonPropertyInfo, typeof(object), options); } // Verify that we have a valid enumerable. Type arrayType = jsonPropertyInfo.RuntimePropertyType; if (!typeof(IEnumerable).IsAssignableFrom(arrayType)) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(arrayType); } Debug.Assert(state.Current.IsProcessingCollection()); if (state.Current.CollectionPropertyInitialized) { // A nested json array so push a new stack frame. Type elementType = jsonPropertyInfo.ElementClassInfo.Type; state.Push(); state.Current.Initialize(elementType, options); } state.Current.CollectionPropertyInitialized = true; // We should not be processing custom converters here (converters are of ClassType.Value). Debug.Assert(state.Current.JsonClassInfo.ClassType != ClassType.Value); // Set or replace the existing enumerable value. object value = ReadStackFrame.CreateEnumerableValue(ref reader, ref state); // If value is not null, then we don't have a converter so apply the value. if (value != null) { if (state.Current.ReturnValue != null) { state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value); } else { // Primitive arrays being returned without object state.Current.SetReturnValue(value); } } }