internal override bool OnTryWrite(BinaryWriter writer, T value, BinarySerializerOptions options, ref WriteStack state) { // Minimize boxing for structs by only boxing once here object objectValue = value !; if (!state.SupportContinuation) { writer.WriteStartObject(); if (BinarySerializer.WriteReferenceForObject(this, objectValue, ref state, writer)) { writer.WriteEndObject(); return(true); } var binaryClassInfo = state.Current.BinaryClassInfo; BinaryPropertyInfo dataExtensionProperty = binaryClassInfo.DataExtensionProperty; int propertyCount = 0; BinaryPropertyInfo[] propertyCacheArray = binaryClassInfo.PropertyCacheArray; if (propertyCacheArray != null) { propertyCount = propertyCacheArray.Length; } for (int i = 0; i < propertyCount; i++) { BinaryPropertyInfo binaryPropertyInfo = propertyCacheArray ![i];
internal sealed override bool OnTryRead(ref BinaryReader reader, Type typeToConvert, BinarySerializerOptions options, ref ReadStack state, [MaybeNullWhen(false)] out T value) { object obj; ArgumentState argumentState = state.Current.CtorArgumentState !; if (state.Current.ObjectState == StackFrameObjectState.None) { if (!reader.ReadStartToken()) { value = default; return(false); } RefState refState = BinarySerializer.ReadReferenceForObject(this, ref state, ref reader, out object refValue); if (refState == RefState.None) { state.Current.ObjectState = StackFrameObjectState.StartToken; BeginRead(ref state, ref reader, options); // 初始化中可能会修改状态对象 argumentState = state.Current.CtorArgumentState !; } else { state.Current.ObjectState = StackFrameObjectState.CreatedObject; state.Current.ReturnValue = refValue; state.Current.RefState = refState; } } // 读取构造参数 if (!ReadConstructorArgumentsWithContinuation(ref state, ref reader, options)) { value = default; return(false); } if (state.Current.ObjectState < StackFrameObjectState.CreatedObject) { obj = CreateObject(ref state.Current); state.ReferenceResolver.AddReferenceObject(state.Current.RefId, obj); } else { obj = state.Current.ReturnValue; } if (argumentState.FoundPropertyCount > 0) { for (int i = 0; i < argumentState.FoundPropertyCount; i++) { BinaryPropertyInfo binaryPropertyInfo = argumentState.FoundPropertiesAsync ![i].Item1;
private bool HandlePropertyWithContinuation( ref ReadStack state, ref BinaryReader reader, BinaryPropertyInfo binaryPropertyInfo) { if (state.Current.PropertyState < StackFramePropertyState.ReadValue) { if (!binaryPropertyInfo.ShouldDeserialize) { if (!reader.TrySkip(state.Options)) { return(false); } state.Current.EndProperty(); return(true); } } object propValue = default; if (state.Current.UseExtensionProperty) { // TODO 扩展属性 } else { if (!binaryPropertyInfo.ReadBinaryAsObject(ref state, ref reader, out propValue)) { return(false); } } Debug.Assert(binaryPropertyInfo.ShouldDeserialize); Dictionary <string, object> argumentState = state.Current.PropertyValueCache !; if (argumentState == null) { state.Current.PropertyValueCache = new Dictionary <string, object>(state.Current.BinaryClassInfo.PropertyCacheArray.Length); argumentState = state.Current.PropertyValueCache; } argumentState[binaryPropertyInfo.NameAsString] = propValue; state.Current.EndProperty(); return(true); }
public override void Initialize( TypeMap typeMap, Type runtimePropertyType, ParameterInfo parameterInfo, BinaryPropertyInfo matchingProperty, BinarySerializerOptions options) { base.Initialize( typeMap, runtimePropertyType, parameterInfo, matchingProperty, options); if (parameterInfo != null && parameterInfo.HasDefaultValue) { DefaultValue = parameterInfo.DefaultValue; TypedDefaultValue = (T)parameterInfo.DefaultValue !; } else { DefaultValue = TypedDefaultValue; } }
public PropertyRef(ulong key, BinaryPropertyInfo info, byte[] nameFromBinary) { Key = key; Info = info; NameFromBinary = nameFromBinary; }
internal override bool OnTryRead(ref BinaryReader reader, Type typeToConvert, BinarySerializerOptions options, ref ReadStack state, [MaybeNullWhen(false)] out T value) { object obj; if (state.UseFastPath) { // 刚进入对象读取 if (reader.CurrentTypeInfo == null || reader.CurrentTypeInfo.SerializeType != ClassType.Object) { ThrowHelper.ThrowBinaryException_DeserializeUnableToConvertValue(TypeToConvert); } reader.AheadReadStartToken(); if (state.Current.BinaryClassInfo.CreateObject == null) { ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(state.Current.BinaryClassInfo.Type, ref reader, ref state); } RefState refState = BinarySerializer.ReadReferenceForObject(this, ref state, ref reader, out object refValue); if (refState == RefState.None) { obj = state.Current.BinaryClassInfo.CreateObject(); state.ReferenceResolver.AddReferenceObject(state.Current.RefId, obj); } else { obj = refValue; } // Process all properties. while (true) { reader.AheadReadPropertyName(); BinaryPropertyInfo binaryPropertyInfo = null; state.Current.PropertyState = StackFramePropertyState.Name; if (reader.TokenType == BinaryTokenType.EndObject) { break; } Debug.Assert(reader.TokenType == BinaryTokenType.PropertyName); ushort propertySeq = reader.CurrentPropertySeq; BinaryMemberInfo mi = state.GetMemberInfo(propertySeq); // Debug.Assert(mi != null); binaryPropertyInfo = BinarySerializer.LookupProperty( obj, mi.NameAsUtf8Bytes, ref state, out bool useExtensionProperty); state.Current.UseExtensionProperty = useExtensionProperty; // binaryPropertyInfo = state.LookupProperty(mi.NameAsString); state.Current.BinaryPropertyInfo = binaryPropertyInfo; state.Current.PropertyPolymorphicConverter = null; if (binaryPropertyInfo == null) { if (!reader.TrySkip(options)) { value = default; return(false); } state.Current.EndProperty(); continue; } if (!binaryPropertyInfo.ShouldDeserialize) { if (!reader.TrySkip(options)) { state.Current.ReturnValue = obj; value = default; return(false); } state.Current.EndProperty(); continue; } // Obtain the CLR value from the Binary and set the member. if (!state.Current.UseExtensionProperty) { binaryPropertyInfo.ReadBinaryAndSetMember(obj, ref state, ref reader); } else { // TODO 扩展属性 } state.Current.EndProperty(); } } else { // Slower path that supports continuation and preserved references. if (state.Current.ObjectState == StackFrameObjectState.None) { // 刚进入对象读取 if (reader.CurrentTypeInfo == null || reader.CurrentTypeInfo.SerializeType != ClassType.Object) { ThrowHelper.ThrowBinaryException_DeserializeUnableToConvertValue(TypeToConvert); } if (!reader.ReadStartToken()) { value = default; return(false); } RefState refState = BinarySerializer.ReadReferenceForObject(this, ref state, ref reader, out object refValue); if (refState == RefState.None) { state.Current.ObjectState = StackFrameObjectState.StartToken; } else if (refState == RefState.Created) { state.Current.ObjectState = StackFrameObjectState.CreatedObject; state.Current.ReturnValue = refValue; } } // 创建对象 if (state.Current.ObjectState < StackFrameObjectState.CreatedObject) { if (state.Current.BinaryClassInfo.CreateObject == null) { ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(state.Current.BinaryClassInfo.Type, ref reader, ref state); } obj = state.Current.BinaryClassInfo.CreateObject(); state.ReferenceResolver.AddReferenceObject(state.Current.RefId, obj); state.Current.ReturnValue = obj; state.Current.ObjectState = StackFrameObjectState.CreatedObject; } else { obj = state.Current.ReturnValue !; Debug.Assert(obj != null); } // Process all properties. while (true) { // Determine the property. // 读取属性索引 if (state.Current.PropertyState == StackFramePropertyState.None) { if (!reader.ReadPropertyName()) { state.Current.ReturnValue = obj; value = default; return(false); } state.Current.PropertyState = StackFramePropertyState.ReadName; // } BinaryPropertyInfo binaryPropertyInfo; if (state.Current.PropertyState <= StackFramePropertyState.ReadName) { state.Current.PropertyState = StackFramePropertyState.Name; if (reader.TokenType == BinaryTokenType.EndObject) { break; } Debug.Assert(reader.TokenType == BinaryTokenType.PropertyName); ushort propertySeq = reader.CurrentPropertySeq; BinaryMemberInfo mi = state.GetMemberInfo(propertySeq); Debug.Assert(mi != null); binaryPropertyInfo = BinarySerializer.LookupProperty( obj, mi.NameAsUtf8Bytes, ref state, out bool useExtensionProperty); state.Current.UseExtensionProperty = useExtensionProperty; // binaryPropertyInfo = state.LookupProperty(mi.NameAsString); state.Current.BinaryPropertyInfo = binaryPropertyInfo; state.Current.PropertyPolymorphicConverter = null; if (binaryPropertyInfo == null) { state.Current.EndProperty(); continue; } } else { Debug.Assert(state.Current.BinaryPropertyInfo != null); binaryPropertyInfo = state.Current.BinaryPropertyInfo !; } if (state.Current.PropertyState < StackFramePropertyState.ReadValue) { if (!binaryPropertyInfo.ShouldDeserialize) { if (!reader.TrySkip(options)) { state.Current.ReturnValue = obj; value = default; return(false); } state.Current.EndProperty(); continue; } } if (state.Current.PropertyState < StackFramePropertyState.TryRead) { // Obtain the CLR value from the Binary and set the member. if (!state.Current.UseExtensionProperty) { if (!binaryPropertyInfo.ReadBinaryAndSetMember(obj, ref state, ref reader)) { state.Current.ReturnValue = obj; value = default; return(false); } } else { // TODO 扩展属性 } state.Current.EndProperty(); } } } // Check if we are trying to build the sorted cache. if (state.Current.PropertyRefCache != null) { state.Current.BinaryClassInfo.UpdateSortedPropertyCache(ref state.Current); } value = (T)obj; return(true); }