/// <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);
            }
        }
예제 #2
0
                /// <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 });
                    }
                }
예제 #3
0
                /// <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);
            }
        }
예제 #5
0
        /// <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);
            }
        }
예제 #7
0
        /// <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);
            }
        }
예제 #8
0
        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);
                        }
                    }
                }
            }
        }
예제 #9
0
        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);
        }