/// <summary> /// 添加属性 /// </summary> /// <param name="property">属性信息</param> /// <param name="propertyMethod">函数信息</param> public void PushBox(PropertyIndex property, MethodInfo propertyMethod) { Label end = default(Label); MethodInfo isOutputMethod = SerializeMethodCache.GetIsOutputMethod(property.Member.PropertyType); if (isOutputMethod != null) { generator.Emit(OpCodes.Ldarg_0); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.call(propertyMethod); generator.call(isOutputMethod); generator.Emit(OpCodes.Brfalse, end = generator.DefineLabel()); } bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(property.Member.PropertyType, ref isCustom); if (isCustom) { LocalBuilder loadMember = generator.DeclareLocal(property.Member.PropertyType); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.call(propertyMethod); generator.Emit(OpCodes.Stloc_0); generator.Emit(OpCodes.Ldloca_S, loadMember); generator.Emit(OpCodes.Ldarg_0); } else { generator.Emit(OpCodes.Ldarg_0); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.call(propertyMethod); } generator.call(method); if (isOutputMethod != null) { generator.MarkLabel(end); } }
/// <summary> /// 设置字段信息 /// </summary> /// <param name="field"></param> public void Set(KeyValue <FieldIndex, MemberAttribute> field) { this.field = field.Key.Member; Name = field.Key.AnonymousName; if (field.Value != null) { itemName = field.Value.ItemName; } MemberIndex = field.Key.MemberIndex; MethodInfo method = SerializeMethodCache.GetIsOutputMethod(this.field.FieldType); if (method != null) { isOutputMethod = (Func <Serializer, object, bool>) typeof(AutoCSer.Reflection.InvokeMethodReturn <, ,>).MakeGenericType(typeof(Serializer), this.field.FieldType, typeof(bool)).GetMethod("getTypeObjectReturnType", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); } bool isCustom = false; method = SerializeMethodCache.GetMemberMethodInfo(this.field.FieldType, ref isCustom); if (isCustom) { customSerializeMethod = (Action <object, Serializer>) typeof(AutoCSer.Reflection.InvokeMethodRef1 <,>).MakeGenericType(this.field.FieldType, typeof(Serializer)).GetMethod("getObjectType", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); } else { serializeMethod = (Action <Serializer, object>) typeof(AutoCSer.Reflection.InvokeMethod <,>).MakeGenericType(typeof(Serializer), this.field.FieldType).GetMethod("getTypeObject", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); } }
/// <summary> /// 设置属性信息 /// </summary> /// <param name="property"></param> public void Set(PropertyMethod property) { this.PropertyInfo = property.Property.Member; if (PropertyInfo.DeclaringType.IsValueType) { getMethod = (Func <object, object>) typeof(AutoCSer.Reflection.InvokeMethodRefReturn <,>).MakeGenericType(PropertyInfo.DeclaringType, PropertyInfo.PropertyType).GetMethod("getObjectReturn", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { PropertyInfo.GetGetMethod(true) }); } else { getMethod = (Func <object, object>) typeof(AutoCSer.Reflection.InvokeMethodReturn <,>).MakeGenericType(PropertyInfo.DeclaringType, PropertyInfo.PropertyType).GetMethod("getObjectReturn", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { PropertyInfo.GetGetMethod(true) }); } if (property.Attribute != null) { itemName = property.Attribute.ItemName; } MemberIndex = property.Property.MemberIndex; MethodInfo method = SerializeMethodCache.GetIsOutputMethod(this.PropertyInfo.PropertyType); if (method != null) { isOutputMethod = (Func <Serializer, object, bool>) typeof(AutoCSer.Reflection.InvokeMethodReturn <, ,>).MakeGenericType(typeof(Serializer), this.PropertyInfo.PropertyType, typeof(bool)).GetMethod("getTypeObjectReturnType", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); } bool isCustom = false; method = SerializeMethodCache.GetMemberMethodInfo(this.PropertyInfo.PropertyType, ref isCustom); if (isCustom) { customSerializeMethod = (Action <object, Serializer>) typeof(AutoCSer.Reflection.InvokeMethodRef1 <,>).MakeGenericType(PropertyInfo.PropertyType, typeof(Serializer)).GetMethod("getObjectType", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); } else { serializeMethod = (Action <Serializer, object>) typeof(AutoCSer.Reflection.InvokeMethod <,>).MakeGenericType(typeof(Serializer), PropertyInfo.PropertyType).GetMethod("getTypeObject", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); } }
/// <summary> /// 添加字段 /// </summary> /// <param name="field">字段信息</param> public void PushBox(FieldIndex field) { Label end = default(Label); MethodInfo isOutputMethod = SerializeMethodCache.GetIsOutputMethod(field.Member.FieldType); if (isOutputMethod != null) { generator.Emit(OpCodes.Ldarg_0); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.Emit(OpCodes.Ldfld, field.Member); generator.call(isOutputMethod); generator.Emit(OpCodes.Brfalse, end = generator.DefineLabel()); } bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(field.Member.FieldType, ref isCustom); if (isCustom) { if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.Emit(OpCodes.Ldflda, field.Member); generator.Emit(OpCodes.Ldarg_0); } else { generator.Emit(OpCodes.Ldarg_0); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.Emit(OpCodes.Ldfld, field.Member); } generator.call(method); if (isOutputMethod != null) { generator.MarkLabel(end); } }
/// <summary> /// 添加成员 /// </summary> /// <param name="name">成员名称</param> /// <param name="attribute">XML序列化成员配置</param> private void nameStart(string name, MemberAttribute attribute) { generator.charStreamSimpleWriteNotNull(OpCodes.Ldloc_0, SerializeMethodCache.GetNameStartPool(name), name.Length + 2); if (attribute != null && attribute.ItemName != null) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldstr, attribute.ItemName); generator.Emit(OpCodes.Stfld, ItemNameField); } }
/// <summary> /// 添加字段 /// </summary> /// <param name="field">字段信息</param> /// <param name="attribute">XML序列化成员配置</param> public void Push(FieldIndex field, MemberAttribute attribute) { Label end = default(Label); MethodInfo isOutputMethod = SerializeMethodCache.GetIsOutputMethod(field.Member.FieldType); if (isOutputMethod != null) { generator.Emit(OpCodes.Ldarg_0); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.Emit(OpCodes.Ldfld, field.Member); generator.call(isOutputMethod); generator.Emit(OpCodes.Brfalse, end = generator.DefineLabel()); } string name = field.AnonymousName; nameStart(name, attribute); bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(field.Member.FieldType, ref isCustom); if (isCustom) { if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.Emit(OpCodes.Ldflda, field.Member); generator.Emit(OpCodes.Ldarg_0); } else { generator.Emit(OpCodes.Ldarg_0); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.Emit(OpCodes.Ldfld, field.Member); } generator.call(method); WriteName(generator, OpCodes.Ldloc_0, name, true); if (isOutputMethod != null) { generator.MarkLabel(end); } }
/// <summary> /// 添加属性 /// </summary> /// <param name="property">属性信息</param> /// <param name="propertyMethod">函数信息</param> /// <param name="attribute">XML序列化成员配置</param> public void Push(PropertyIndex property, MethodInfo propertyMethod, MemberAttribute attribute) { Label end = default(Label); MethodInfo isOutputMethod = SerializeMethodCache.GetIsOutputMethod(property.Member.PropertyType); if (isOutputMethod != null) { generator.Emit(OpCodes.Ldarg_0); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.call(propertyMethod); generator.call(isOutputMethod); generator.Emit(OpCodes.Brfalse_S, end = generator.DefineLabel()); } nameStart(property.Member.Name, attribute); bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(property.Member.PropertyType, ref isCustom); if (isCustom) { LocalBuilder loadMember = generator.DeclareLocal(property.Member.PropertyType); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.call(propertyMethod); generator.Emit(OpCodes.Stloc_0); generator.Emit(OpCodes.Ldloca_S, loadMember); generator.Emit(OpCodes.Ldarg_0); } else { generator.Emit(OpCodes.Ldarg_0); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.call(propertyMethod); } generator.call(method); generator.charStreamSimpleWriteNotNull(OpCodes.Ldloc_0, SerializeMethodCache.GetNameEndPool(property.Member.Name), property.Member.Name.Length + 3); if (isOutputMethod != null) { generator.MarkLabel(end); } }
static TypeDeSerializer() { Type type = typeof(T); MethodInfo methodInfo = XmlDeSerializer.GetDeSerializeMethod(type); if (methodInfo != null) { DefaultDeSerializer = (XmlDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(XmlDeSerializer.DeSerializeDelegate <T>), methodInfo); return; } if (type.IsArray) { if (type.GetArrayRank() == 1) { DefaultDeSerializer = (XmlDeSerializer.DeSerializeDelegate <T>)GenericType.Get(type.GetElementType()).XmlDeSerializeArrayMethod; } else { DefaultDeSerializer = notSupport; } return; } if (type.IsEnum) { if (type.IsDefined(typeof(FlagsAttribute), false)) { DefaultDeSerializer = (XmlDeSerializer.DeSerializeDelegate <T>)EnumGenericType.Get(type).XmlDeSerializeEnumFlagsDelegate; } else { DefaultDeSerializer = (XmlDeSerializer.DeSerializeDelegate <T>)EnumGenericType.Get(type).XmlDeSerializeEnumDelegate; } return; } if (type.IsInterface || type.IsPointer || typeof(Delegate).IsAssignableFrom(type)) { DefaultDeSerializer = notSupport; return; } if (type.IsGenericType) { Type genericType = type.GetGenericTypeDefinition(); if (genericType == typeof(Nullable <>)) { Type[] parameterTypes = type.GetGenericArguments(); DefaultDeSerializer = (XmlDeSerializer.DeSerializeDelegate <T>)(parameterTypes[0].IsEnum ? StructGenericType.Get(parameterTypes[0]).XmlDeSerializeNullableEnumMethod : StructGenericType.Get(parameterTypes[0]).XmlDeSerializeNullableMethod); return; } if (genericType == typeof(KeyValuePair <,>)) { DefaultDeSerializer = (XmlDeSerializer.DeSerializeDelegate <T>)GenericType2.Get(type.GetGenericArguments()).XmlDeSerializeKeyValuePairMethod; isValueType = true; return; } } if ((methodInfo = DeSerializeMethodCache.GetCustom(type)) != null) { if (type.IsValueType) { #if NOJIT DefaultDeSerializer = new CustomDeSerializer(methodInfo).DeSerialize; #else DynamicMethod dynamicMethod = new DynamicMethod("CustomXmlDeSerializer", null, new Type[] { typeof(XmlDeSerializer), type.MakeByRefType() }, type, true); ILGenerator generator = dynamicMethod.GetILGenerator(); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldarg_0); generator.call(methodInfo); generator.Emit(OpCodes.Ret); DefaultDeSerializer = (XmlDeSerializer.DeSerializeDelegate <T>)dynamicMethod.CreateDelegate(typeof(XmlDeSerializer.DeSerializeDelegate <T>)); #endif } else { DefaultDeSerializer = (XmlDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(XmlDeSerializer.DeSerializeDelegate <T>), methodInfo); } } else { Type attributeType; attribute = type.customAttribute <XmlSerializeAttribute>(out attributeType) ?? XmlSerializer.AllMemberAttribute; if ((methodInfo = DeSerializeMethodCache.GetIEnumerableConstructor(type)) != null) { DefaultDeSerializer = (XmlDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(XmlDeSerializer.DeSerializeDelegate <T>), methodInfo); } else { if (type.IsValueType) { isValueType = true; } else if (attribute != XmlSerializer.AllMemberAttribute && attributeType != type) { for (Type baseType = type.BaseType; baseType != typeof(object); baseType = baseType.BaseType) { XmlSerializeAttribute baseAttribute = baseType.customAttribute <XmlSerializeAttribute>(); if (baseAttribute != null) { if (baseAttribute.IsBaseType) { methodInfo = DeSerializeMethodCache.BaseDeSerializeMethod.MakeGenericMethod(baseType, type); DefaultDeSerializer = (XmlDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(XmlDeSerializer.DeSerializeDelegate <T>), methodInfo); return; } break; } } } if (type.IsValueType) { foreach (AutoCSer.Metadata.AttributeMethod attributeMethod in AutoCSer.Metadata.AttributeMethod.GetStatic(type)) { if (attributeMethod.Method.ReturnType == typeof(bool)) { ParameterInfo[] parameters = attributeMethod.Method.GetParameters(); if (parameters.Length == 2 && parameters[0].ParameterType == typeof(XmlDeSerializer) && parameters[1].ParameterType == Emit.Pub.PointerSizeRefType) { if (attributeMethod.GetAttribute <UnknownNameAttribute>() != null) { #if NOJIT onUnknownName = new UnknownDeSerializer(methodInfo).DeSerialize; #else DynamicMethod dynamicMethod = new DynamicMethod("XmlUnknownDeSerialize", null, new Type[] { typeof(XmlDeSerializer), type.MakeByRefType(), Emit.Pub.PointerSizeRefType }, type, true); ILGenerator generator = dynamicMethod.GetILGenerator(); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldarg_2); generator.call(methodInfo); generator.Emit(OpCodes.Ret); onUnknownName = (UnknownDeSerialize)dynamicMethod.CreateDelegate(typeof(UnknownDeSerialize)); #endif break; } } } } } else { Type refType = type.MakeByRefType(); foreach (AutoCSer.Metadata.AttributeMethod attributeMethod in AutoCSer.Metadata.AttributeMethod.GetStatic(type)) { if (attributeMethod.Method.ReturnType == typeof(bool)) { ParameterInfo[] parameters = attributeMethod.Method.GetParameters(); if (parameters.Length == 3 && parameters[0].ParameterType == typeof(XmlDeSerializer) && parameters[1].ParameterType == refType && parameters[2].ParameterType == Emit.Pub.PointerSizeRefType) { if (attributeMethod.GetAttribute <UnknownNameAttribute>() != null) { onUnknownName = (UnknownDeSerialize)Delegate.CreateDelegate(typeof(UnknownDeSerialize), attributeMethod.Method); break; } } } } } FieldIndex defaultMember = null; LeftArray <KeyValue <FieldIndex, XmlSerializeMemberAttribute> > fields = SerializeMethodCache.GetFields(MemberIndexGroup <T> .GetFields(attribute.MemberFilters), attribute); LeftArray <PropertyMethod> properties = DeSerializeMethodCache.GetProperties(MemberIndexGroup <T> .GetProperties(attribute.MemberFilters), attribute); bool isBox = false; if (type.IsValueType && fields.Length + properties.Length == 1) { BoxSerializeAttribute boxSerialize = AutoCSer.Metadata.TypeAttribute.GetAttribute <BoxSerializeAttribute>(type); if (boxSerialize != null && boxSerialize.IsXml) { isBox = true; defaultMember = null; } } TryDeSerializeFilter[] deSerializers = new TryDeSerializeFilter[fields.Length + properties.Length + (defaultMember == null ? 0 : 1)]; //memberMap.type memberMapType = memberMap<valueType>.TypeInfo; string[] names = isBox ? null : new string[deSerializers.Length]; int index = 0, nameLength = 0, maxNameLength = 0; foreach (KeyValue <FieldIndex, XmlSerializeMemberAttribute> member in fields) { TryDeSerializeFilter tryDeSerialize = deSerializers[index] = new TryDeSerializeFilter { #if NOJIT TryDeSerialize = new FieldDeSerializer(member.Key.Member).DeSerializer(), #else TryDeSerialize = (XmlDeSerializer.DeSerializeDelegate <T>)DeSerializeMethodCache.CreateDynamicMethod(type, member.Key.Member).CreateDelegate(typeof(XmlDeSerializer.DeSerializeDelegate <T>)), #endif ItemName = member.Value == null ? null : member.Value.ItemName, MemberMapIndex = member.Key.MemberIndex, //MemberFilter = member.Key.Member.IsPublic ? MemberFilters.PublicInstanceField : MemberFilters.NonPublicInstanceField }; if (!isBox) { string name = member.Key.AnonymousName; if (name.Length > maxNameLength) { maxNameLength = name.Length; } nameLength += (names[index++] = name).Length; if (member.Key == defaultMember) { deSerializers[deSerializers.Length - 1] = tryDeSerialize; names[deSerializers.Length - 1] = string.Empty; } } } foreach (PropertyMethod member in properties) { deSerializers[index] = new TryDeSerializeFilter { #if NOJIT TryDeSerialize = new PropertyDeSerializer(member.Property.Member).DeSerializer(), #else TryDeSerialize = (XmlDeSerializer.DeSerializeDelegate <T>)DeSerializeMethodCache.CreateDynamicMethod(type, member.Property.Member, member.Method).CreateDelegate(typeof(XmlDeSerializer.DeSerializeDelegate <T>)), #endif ItemName = member.Attribute == null ? null : member.Attribute.ItemName, MemberMapIndex = member.Property.MemberIndex, //MemberFilter = member.Method.IsPublic ? MemberFilters.PublicInstanceProperty : MemberFilters.NonPublicInstanceProperty }; if (!isBox) { if (member.Property.Member.Name.Length > maxNameLength) { maxNameLength = member.Property.Member.Name.Length; } nameLength += (names[index++] = member.Property.Member.Name).Length; } } memberDeSerializers = deSerializers; if (isBox) { DefaultDeSerializer = unbox; } else { if (type.Name[0] == '<') { isAnonymousType = true; } if (maxNameLength > (short.MaxValue >> 1) - 2 || nameLength == 0) { memberNames = Unmanaged.NullByte8; } else { memberNames = Unmanaged.GetStaticPointer((nameLength + (names.Length - (defaultMember == null ? 0 : 1)) * 3 + 1) << 1, false); byte *write = memberNames.Byte; foreach (string name in names) { if (name.Length != 0) { *(short *)write = (short)((name.Length + 2) * sizeof(char)); *(char *)(write + sizeof(short)) = '<'; fixed(char *nameFixed = name) AutoCSer.Extensions.StringExtension.SimpleCopyNotNull(nameFixed, (char *)(write + (sizeof(short) + sizeof(char))), name.Length); *(char *)(write += (sizeof(short) + sizeof(char)) + (name.Length << 1)) = '>'; write += sizeof(char); } } *(short *)write = 0; } if (type.IsGenericType) { memberSearcher = DeSerializeMethodCache.GetGenericDefinitionMemberSearcher(type, names); } else { memberSearcher = AutoCSer.StateSearcher.CharBuilder.Create(names, true); } } } } }
static TypeSerializer() { Type type = typeof(valueType); MethodInfo methodInfo = XmlSerializer.GetSerializeMethod(type); if (methodInfo != null) { defaultSerializer = (Action <XmlSerializer, valueType>)Delegate.CreateDelegate(typeof(Action <XmlSerializer, valueType>), methodInfo); isValueType = true; return; } if (type.IsArray) { if (type.GetArrayRank() == 1) { defaultSerializer = (Action <XmlSerializer, valueType>)SerializeMethodCache.GetArray(type.GetElementType()); } else { defaultSerializer = ignore; } isValueType = true; return; } if (type.IsEnum) { defaultSerializer = enumToString; isValueType = true; return; } if (type.IsInterface || type.IsPointer || typeof(Delegate).IsAssignableFrom(type)) { defaultSerializer = ignore; isValueType = true; return; } if (type.IsGenericType) { Type genericType = type.GetGenericTypeDefinition(); if (genericType == typeof(Nullable <>)) { defaultSerializer = (Action <XmlSerializer, valueType>)StructGenericType.Get(type.GetGenericArguments()[0]).XmlSerializeNullableMethod; isValueType = true; return; } } if ((methodInfo = SerializeMethodCache.GetCustom(type)) != null) { if (type.IsValueType) { #if NOJIT defaultSerializer = new CustomSerializer(methodInfo).Serialize; #else DynamicMethod dynamicMethod = new DynamicMethod("CustomXmlSerializer", null, new Type[] { typeof(XmlSerializer), type }, type, true); ILGenerator generator = dynamicMethod.GetILGenerator(); generator.Emit(OpCodes.Ldarga_S, 1); generator.Emit(OpCodes.Ldarg_0); generator.call(methodInfo); generator.Emit(OpCodes.Ret); defaultSerializer = (Action <XmlSerializer, valueType>)dynamicMethod.CreateDelegate(typeof(Action <XmlSerializer, valueType>)); #endif } else { defaultSerializer = (Action <XmlSerializer, valueType>)Delegate.CreateDelegate(typeof(Action <XmlSerializer, valueType>), methodInfo); } isValueType = true; } else { Delegate enumerableDelegate = SerializeMethodCache.GetIEnumerable(type); if (enumerableDelegate != null) { defaultSerializer = (Action <XmlSerializer, valueType>)enumerableDelegate; isValueType = true; } else { Type attributeType; attribute = type.customAttribute <XmlSerializeAttribute>(out attributeType) ?? (type.Name[0] == '<' ? XmlSerializeAttribute.AnonymousTypeMember : XmlSerializer.DefaultAttribute); if (type.IsValueType) { isValueType = true; } else if (attribute != XmlSerializer.DefaultAttribute && attributeType != type) { for (Type baseType = type.BaseType; baseType != typeof(object); baseType = baseType.BaseType) { XmlSerializeAttribute baseAttribute = baseType.customAttribute <XmlSerializeAttribute>(); if (baseAttribute != null) { if (baseAttribute.IsBaseType) { methodInfo = SerializeMethodCache.BaseSerializeMethod.MakeGenericMethod(baseType, type); defaultSerializer = (Action <XmlSerializer, valueType>)Delegate.CreateDelegate(typeof(Action <XmlSerializer, valueType>), methodInfo); return; } break; } } } LeftArray <KeyValue <FieldIndex, XmlSerializeMemberAttribute> > fields = SerializeMethodCache.GetFields(MemberIndexGroup <valueType> .GetFields(attribute.MemberFilters), attribute); LeftArray <PropertyMethod> properties = SerializeMethodCache.GetProperties(MemberIndexGroup <valueType> .GetProperties(attribute.MemberFilters), attribute); bool isBox = false; if (type.IsValueType && fields.Length + properties.Length == 1) { BoxSerializeAttribute boxSerialize = AutoCSer.Metadata.TypeAttribute.GetAttribute <BoxSerializeAttribute>(type); if (boxSerialize != null && boxSerialize.IsXml) { isBox = true; } } #if NOJIT if (isBox) { defaultSerializer = memberSerializer = new FieldPropertySerializer(ref fields, ref properties).SerializeBox; } else { memberSerializer = new FieldPropertySerializer(ref fields, ref properties).Serialize; memberMapSerializer = new MemberMapSerializer(ref fields, ref properties).Serialize; } #else SerializeMemberDynamicMethod dynamicMethod = new SerializeMemberDynamicMethod(type); SerializeMemberMapDynamicMethod memberMapDynamicMethod = isBox ? default(SerializeMemberMapDynamicMethod) : new SerializeMemberMapDynamicMethod(type); foreach (KeyValue <FieldIndex, XmlSerializeMemberAttribute> member in fields) { if (isBox) { dynamicMethod.PushBox(member.Key); } else { dynamicMethod.Push(member.Key, member.Value); memberMapDynamicMethod.Push(member.Key, member.Value); } } foreach (PropertyMethod member in properties) { if (isBox) { dynamicMethod.PushBox(member.Property, member.Method); } else { dynamicMethod.Push(member.Property, member.Method, member.Attribute); memberMapDynamicMethod.Push(member.Property, member.Method, member.Attribute); } } memberSerializer = (Action <XmlSerializer, valueType>)dynamicMethod.Create <Action <XmlSerializer, valueType> >(); if (isBox) { defaultSerializer = memberSerializer; } else { memberMapSerializer = (Action <MemberMap, XmlSerializer, valueType>)memberMapDynamicMethod.Create <Action <MemberMap, XmlSerializer, valueType> >(); } #endif } } }
/// <summary> /// 添加字段 /// </summary> /// <param name="field">字段信息</param> /// <param name="attribute">XML序列化成员配置</param> public void Push(FieldIndex field, MemberAttribute attribute) { Label end = generator.DefineLabel(); generator.memberMapIsMember(OpCodes.Ldarg_0, field.MemberIndex); generator.Emit(OpCodes.Brfalse, end); MethodInfo isOutputMethod = SerializeMethodCache.GetIsOutputMethod(field.Member.FieldType); if (isOutputMethod != null) { generator.Emit(OpCodes.Ldarg_1); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 2); } else { generator.Emit(OpCodes.Ldarg_2); } generator.Emit(OpCodes.Ldfld, field.Member); generator.call(isOutputMethod); generator.Emit(OpCodes.Brfalse, end); } string name = field.AnonymousName; SerializeMemberDynamicMethod.WriteName(generator, OpCodes.Ldloc_0, name, false); if (attribute != null && attribute.ItemName != null) { generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldstr, attribute.ItemName); generator.Emit(OpCodes.Stfld, SerializeMemberDynamicMethod.ItemNameField); } bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(field.Member.FieldType, ref isCustom); if (isCustom) { if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 2); } else { generator.Emit(OpCodes.Ldarg_2); } generator.Emit(OpCodes.Ldflda, field.Member); generator.Emit(OpCodes.Ldarg_1); } else { generator.Emit(OpCodes.Ldarg_1); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 2); } else { generator.Emit(OpCodes.Ldarg_2); } generator.Emit(OpCodes.Ldfld, field.Member); } generator.call(method); SerializeMemberDynamicMethod.WriteName(generator, OpCodes.Ldloc_0, name, true); generator.MarkLabel(end); }
/// <summary> /// 添加属性 /// </summary> /// <param name="property">属性信息</param> /// <param name="propertyMethod">函数信息</param> /// <param name="attribute">XML序列化成员配置</param> public void Push(PropertyIndex property, MethodInfo propertyMethod, MemberAttribute attribute) { Label end = generator.DefineLabel(); generator.memberMapIsMember(OpCodes.Ldarg_0, property.MemberIndex); generator.Emit(OpCodes.Brfalse, end); MethodInfo isOutputMethod = SerializeMethodCache.GetIsOutputMethod(property.Member.PropertyType); if (isOutputMethod != null) { generator.Emit(OpCodes.Ldarg_1); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 2); } else { generator.Emit(OpCodes.Ldarg_2); } generator.call(propertyMethod); generator.call(isOutputMethod); generator.Emit(OpCodes.Brfalse, end); } SerializeMemberDynamicMethod.WriteName(generator, OpCodes.Ldloc_0, property.Member.Name, false); if (attribute != null && attribute.ItemName != null) { generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldstr, attribute.ItemName); generator.Emit(OpCodes.Stfld, SerializeMemberDynamicMethod.ItemNameField); } bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(property.Member.PropertyType, ref isCustom); if (isCustom) { LocalBuilder loadMember = generator.DeclareLocal(property.Member.PropertyType); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 2); } else { generator.Emit(OpCodes.Ldarg_2); } generator.call(propertyMethod); generator.Emit(OpCodes.Stloc_0); generator.Emit(OpCodes.Ldloca_S, loadMember); generator.Emit(OpCodes.Ldarg_1); } else { generator.Emit(OpCodes.Ldarg_1); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 2); } else { generator.Emit(OpCodes.Ldarg_2); } generator.call(propertyMethod); } generator.call(method); SerializeMemberDynamicMethod.WriteName(generator, OpCodes.Ldloc_0, property.Member.Name, true); generator.MarkLabel(end); }