예제 #1
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 = generator.DefineLabel();

            generator.memberMapIsMember(OpCodes.Ldarg_0, field.MemberIndex);
            generator.Emit(OpCodes.Brfalse_S, 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_S, end);
            }
            string name = field.AnonymousName;

            generator.charStreamSimpleWriteNotNull(OpCodes.Ldloc_0, SerializeMethodCache.GetNameStartPool(name), name.Length + 2);

            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);

            generator.charStreamSimpleWriteNotNull(OpCodes.Ldloc_0, SerializeMethodCache.GetNameEndPool(name), name.Length + 3);

            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_S, 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_S, end);
            }
            generator.charStreamSimpleWriteNotNull(OpCodes.Ldloc_0, SerializeMethodCache.GetNameStartPool(property.Member.Name), property.Member.Name.Length + 2);

            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);

            generator.charStreamSimpleWriteNotNull(OpCodes.Ldloc_0, SerializeMethodCache.GetNameEndPool(property.Member.Name), property.Member.Name.Length + 3);

            generator.MarkLabel(end);
        }