using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
-using FoundProperties = System.ValueTuple<System.Text.Json.JsonPropertyInfo, System.Text.Json.JsonReaderState, long, byte[]?, string?>;
-using FoundPropertiesAsync = System.ValueTuple<System.Text.Json.JsonPropertyInfo, object?, string?>;
+using FoundProperty = System.ValueTuple<System.Text.Json.JsonPropertyInfo, System.Text.Json.JsonReaderState, long, byte[]?, string?>;
+using FoundPropertyAsync = System.ValueTuple<System.Text.Json.JsonPropertyInfo, object?, string?>;
namespace System.Text.Json.Serialization.Converters
{
internal sealed override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [MaybeNullWhen(false)] out T value)
{
object obj;
+ ArgumentState argumentState = state.Current.CtorArgumentState!;
if (state.UseFastPath)
{
obj = CreateObject(ref state.Current);
- if (state.Current.PropertyIndex > 0)
+ if (argumentState.FoundPropertyCount > 0)
{
Utf8JsonReader tempReader;
- for (int i = 0; i < state.Current.PropertyIndex; i++)
+ FoundProperty[]? properties = argumentState.FoundProperties;
+ Debug.Assert(properties != null);
+
+ for (int i = 0; i < argumentState.FoundPropertyCount; i++)
{
- JsonPropertyInfo jsonPropertyInfo = state.Current.CtorArgumentState!.FoundProperties![i].Item1;
- long resumptionByteIndex = state.Current.CtorArgumentState.FoundProperties[i].Item3;
- byte[]? propertyNameArray = state.Current.CtorArgumentState.FoundProperties[i].Item4;
- string? dataExtKey = state.Current.CtorArgumentState.FoundProperties[i].Item5;
+ JsonPropertyInfo jsonPropertyInfo = properties[i].Item1;
+ long resumptionByteIndex = properties[i].Item3;
+ byte[]? propertyNameArray = properties[i].Item4;
+ string? dataExtKey = properties[i].Item5;
tempReader = new Utf8JsonReader(
originalSpan.Slice(checked((int)resumptionByteIndex)),
isFinalBlock: true,
- state: state.Current.CtorArgumentState.FoundProperties[i].Item2);
+ state: properties[i].Item2);
Debug.Assert(tempReader.TokenType == JsonTokenType.PropertyName);
ReadPropertyValue(obj, ref state, ref tempReader, jsonPropertyInfo, useExtensionProperty);
}
- ArrayPool<FoundProperties>.Shared.Return(state.Current.CtorArgumentState!.FoundProperties!, clearArray: true);
+ ArrayPool<FoundProperty>.Shared.Return(argumentState.FoundProperties!, clearArray: true);
+ argumentState.FoundProperties = null;
}
}
else
obj = CreateObject(ref state.Current);
- if (state.Current.CtorArgumentState!.FoundPropertyCount > 0)
+ if (argumentState.FoundPropertyCount > 0)
{
- // Set the properties we've parsed so far.
- for (int i = 0; i < state.Current.CtorArgumentState!.FoundPropertyCount; i++)
+ for (int i = 0; i < argumentState.FoundPropertyCount; i++)
{
- JsonPropertyInfo jsonPropertyInfo = state.Current.CtorArgumentState!.FoundPropertiesAsync![i].Item1;
- object? propValue = state.Current.CtorArgumentState!.FoundPropertiesAsync![i].Item2;
- string? dataExtKey = state.Current.CtorArgumentState!.FoundPropertiesAsync![i].Item3;
+ JsonPropertyInfo jsonPropertyInfo = argumentState.FoundPropertiesAsync![i].Item1;
+ object? propValue = argumentState.FoundPropertiesAsync![i].Item2;
+ string? dataExtKey = argumentState.FoundPropertiesAsync![i].Item3;
if (dataExtKey == null)
{
}
}
- ArrayPool<FoundPropertiesAsync>.Shared.Return(state.Current.CtorArgumentState!.FoundPropertiesAsync!, clearArray: true);
+ ArrayPool<FoundPropertyAsync>.Shared.Return(argumentState.FoundPropertiesAsync!, clearArray: true);
+ argumentState.FoundPropertiesAsync = null;
}
}
}
// Check if we are trying to build the sorted parameter cache.
- if (state.Current.CtorArgumentState!.ParameterRefCache != null)
+ if (argumentState.ParameterRefCache != null)
{
state.Current.JsonClassInfo.UpdateSortedParameterCache(ref state.Current);
}
out _,
createExtensionProperty: false);
- if (state.Current.CtorArgumentState!.FoundProperties == null)
- {
- state.Current.CtorArgumentState.FoundProperties =
- ArrayPool<FoundProperties>.Shared.Rent(Math.Max(1, state.Current.JsonClassInfo.PropertyCache!.Count));
- }
- else if (state.Current.PropertyIndex - 1 == state.Current.CtorArgumentState.FoundProperties!.Length)
+ if (jsonPropertyInfo.ShouldDeserialize)
{
- // Rare case where we can't fit all the JSON properties in the rented pool; we have to grow.
- // This could happen if there are duplicate properties in the JSON.
+ ArgumentState argumentState = state.Current.CtorArgumentState!;
+
+ if (argumentState.FoundProperties == null)
+ {
+ argumentState.FoundProperties =
+ ArrayPool<FoundProperty>.Shared.Rent(Math.Max(1, state.Current.JsonClassInfo.PropertyCache!.Count));
+ }
+ else if (argumentState.FoundPropertyCount == argumentState.FoundProperties.Length)
+ {
+ // Rare case where we can't fit all the JSON properties in the rented pool; we have to grow.
+ // This could happen if there are duplicate properties in the JSON.
- var newCache = ArrayPool<FoundProperties>.Shared.Rent(state.Current.CtorArgumentState.FoundProperties!.Length * 2);
+ var newCache = ArrayPool<FoundProperty>.Shared.Rent(argumentState.FoundProperties.Length * 2);
- state.Current.CtorArgumentState.FoundProperties!.CopyTo(newCache, 0);
+ argumentState.FoundProperties.CopyTo(newCache, 0);
- ArrayPool<FoundProperties>.Shared.Return(state.Current.CtorArgumentState.FoundProperties!, clearArray: true);
+ ArrayPool<FoundProperty>.Shared.Return(argumentState.FoundProperties, clearArray: true);
- state.Current.CtorArgumentState.FoundProperties = newCache!;
- }
+ argumentState.FoundProperties = newCache!;
+ }
- state.Current.CtorArgumentState!.FoundProperties![state.Current.PropertyIndex - 1] = (
- jsonPropertyInfo,
- reader.CurrentState,
- reader.BytesConsumed,
- state.Current.JsonPropertyName,
- state.Current.JsonPropertyNameAsString);
+ argumentState.FoundProperties[argumentState.FoundPropertyCount++] = (
+ jsonPropertyInfo,
+ reader.CurrentState,
+ reader.BytesConsumed,
+ state.Current.JsonPropertyName,
+ state.Current.JsonPropertyNameAsString);
+ }
reader.Skip();
}
}
+ Debug.Assert(jsonPropertyInfo.ShouldDeserialize);
+
// Ensure that the cache has enough capacity to add this property.
- if (state.Current.CtorArgumentState!.FoundPropertiesAsync == null)
+ ArgumentState argumentState = state.Current.CtorArgumentState!;
+
+ if (argumentState.FoundPropertiesAsync == null)
{
- state.Current.CtorArgumentState.FoundPropertiesAsync =
- ArrayPool<FoundPropertiesAsync>.Shared.Rent(Math.Max(1, state.Current.JsonClassInfo.PropertyCache!.Count));
+ argumentState.FoundPropertiesAsync = ArrayPool<FoundPropertyAsync>.Shared.Rent(Math.Max(1, state.Current.JsonClassInfo.PropertyCache!.Count));
}
- else if (state.Current.CtorArgumentState.FoundPropertyCount == state.Current.CtorArgumentState.FoundPropertiesAsync!.Length)
+ else if (argumentState.FoundPropertyCount == argumentState.FoundPropertiesAsync!.Length)
{
// Rare case where we can't fit all the JSON properties in the rented pool; we have to grow.
// This could happen if there are duplicate properties in the JSON.
- var newCache = ArrayPool<FoundPropertiesAsync>.Shared.Rent(
- state.Current.CtorArgumentState.FoundPropertiesAsync!.Length * 2);
+ var newCache = ArrayPool<FoundPropertyAsync>.Shared.Rent(argumentState.FoundPropertiesAsync!.Length * 2);
- state.Current.CtorArgumentState.FoundPropertiesAsync!.CopyTo(newCache, 0);
+ argumentState.FoundPropertiesAsync!.CopyTo(newCache, 0);
- ArrayPool<FoundPropertiesAsync>.Shared.Return(
- state.Current.CtorArgumentState.FoundPropertiesAsync!, clearArray: true);
+ ArrayPool<FoundPropertyAsync>.Shared.Return(argumentState.FoundPropertiesAsync!, clearArray: true);
- state.Current.CtorArgumentState.FoundPropertiesAsync = newCache!;
+ argumentState.FoundPropertiesAsync = newCache!;
}
// Cache the property name and value.
- state.Current.CtorArgumentState.FoundPropertiesAsync[state.Current.CtorArgumentState.FoundPropertyCount++] = (
+ argumentState.FoundPropertiesAsync![argumentState.FoundPropertyCount++] = (
jsonPropertyInfo,
propValue,
state.Current.JsonPropertyNameAsString);