Пример #1
0
        public void EndSetMembers(CodeGenerator generator, ArgBuilder targetObject)
        {
            generator.Ldarg(targetObject);
            generator.Load(null);
            generator.If(Cmp.EqualTo);
            generator.Pop();
            LocalBuilder dataRow = generator.DeclareLocal(typeof(DataRow));
            generator.Ldloc(locDataTable);
            generator.Call(typeof(DataTable).GetMethod("NewRow"));
            generator.Stloc(dataRow);

            LocalBuilder locCurrent = generator.DeclareLocal(typeof(string));
            LocalBuilder locEnumerator = generator.DeclareLocal(typeof(Dictionary<string, object>.KeyCollection.Enumerator));

            generator.Ldloc(locMemberValues);
            generator.Call(typeof(Dictionary<string, object>).GetMethod("get_Keys"));
            generator.Call(typeof(Dictionary<string, object>.KeyCollection).GetMethod("GetEnumerator"));
            generator.Stloc(locEnumerator);
            MethodInfo getCurrentMethod = typeof(Dictionary<string, object>.KeyCollection.Enumerator).GetMethod("get_Current");
            MethodInfo moveNextMethod = typeof(Dictionary<string, object>.KeyCollection.Enumerator).GetMethod("MoveNext");
            generator.ForEach(locCurrent, typeof(string), typeof(Dictionary<string, object>.KeyCollection.Enumerator), locEnumerator, getCurrentMethod);

            generator.Ldloc(dataRow);
            generator.Ldloc(locCurrent);

            generator.Ldloc(locMemberValues);
            generator.Ldloc(locCurrent);
            generator.Call(typeof(Dictionary<string, object>).GetMethod("get_Item"));

            generator.Call(typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) }));
            generator.EndForEach(moveNextMethod);
            generator.Ldloc(dataRow);
            generator.EndIf();
        }
Пример #2
0
 public void BeginSetMembers(CodeGenerator generator, ArgBuilder targetObject)
 {
     locMemberValues = generator.DeclareLocal(typeof(Dictionary<string, object>), "memberValues");
     locDataTable = generator.DeclareLocal(typeof(DataTable), "dataTable");
     generator.New(typeof(Dictionary<string, object>).GetConstructor(Type.EmptyTypes));
     generator.Stloc(locMemberValues);
     generator.New(typeof(DataTable).GetConstructor(Type.EmptyTypes));
     generator.Stloc(locDataTable);
 }
Пример #3
0
        public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue)
        {
            LocalBuilder locValue = generator.DeclareLocal(typeof(string));
            Type targetType = memberValue.LocalType;
            Type originalType = ConvertorGeneratorHelper.GetOriginalType(targetType);

            generator.Ldarg(targetObject);
            generator.Load(memberName);
            generator.Call(typeof(NameValueCollection).GetMethod("get_Item", new Type[] { typeof(string) }));
            generator.Stloc(locValue);

            if (targetType.IsAssignableFrom(typeof(string)))
            {
                generator.Ldloc(locValue);
                generator.Stloc(memberValue);
                return;
            }
            else
            {
                generator.Ldloc(locValue);
                generator.Call(typeof(string).GetMethod("IsNullOrEmpty"));
                generator.Load(true);
                generator.If(Cmp.NotEqualTo);
                if (targetType == typeof(Guid))
                {
                    generator.Ldloc(locValue);
                    generator.New(typeof(Guid).GetConstructor(new Type[] { typeof(string) }));
                    generator.Stloc(memberValue);
                }
                else
                {
                    MethodInfo parseMethod = targetType.GetMethod("Parse", new Type[] { typeof(string) });
                    if (parseMethod != null)
                    {
                        generator.Ldloc(locValue);
                        generator.Call(parseMethod);
                        generator.Stloc(memberValue);
                    }
                    else
                    {
                        generator.Ldloc(locValue);
                        generator.Load(originalType);
                        generator.Call(typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) }));
                        if (targetType.IsValueType)
                        {
                            generator.UnboxAny(targetType);
                        }
                        generator.Stloc(memberValue);
                    }
                }
                generator.Else();
                generator.LoadDefaultValue(targetType);
                generator.Stloc(memberValue);
                generator.EndIf();
            }
        }
Пример #4
0
        public override ConvertHandler GetConvertHandler(Type inputType, Type outputType, object inputObject, object outputObject, Dictionary<string, string> mappingNames, List<string> ignoreList, Dictionary<int, string> mappingOrders, bool mappingSpecifiedOnly)
        {
            Dictionary<string, string> distToSrc = new Dictionary<string, string>();
            Dictionary<string, MemberInfo> members = new Dictionary<string, MemberInfo>();
            foreach (string sourceName in mappingNames.Keys)
            {
                MemberInfo sourceMember = ConvertorGeneratorHelper.GetMemberInfo(inputType, sourceName);
                Check.Require(sourceMember != null, string.Format("member named {0} could not be found in {1}", sourceName, outputType.FullName));
                distToSrc.Add(mappingNames[sourceName], sourceName);
                members.Add(mappingNames[sourceName], sourceMember);
            }
            if (!mappingSpecifiedOnly)
            {
                Dictionary<string, MemberInfo> sourceMembers = ConvertorGeneratorHelper.GetMembers(inputType);
                foreach (string sourceName in sourceMembers.Keys)
                {
                    if (!ignoreList.Contains(sourceName) && !distToSrc.ContainsKey(sourceName))
                    {
                        distToSrc.Add(sourceName, sourceName);
                        members.Add(sourceName, sourceMembers[sourceName]);
                    }
                }
            }

            CodeGenerator gen = new CodeGenerator();
            gen.BeginMethod("m" + Guid.NewGuid().ToString("N"), typeof(ConvertHandler));

            ArgBuilder inputObjectArg = new ArgBuilder(0, inputType);
            ArgBuilder outputObjectArg = new ArgBuilder(1, outputType);

            int currentCount = 0;
            int memberCount = members.Count;
            string[] keys = new string[memberCount];
            distToSrc.Keys.CopyTo(keys, 0);
            List<string> keyList = new List<string>(keys);
            MemberSetterGenerator.BeginSetMembers(gen, outputObjectArg);
            while (currentCount < memberCount)
            {
                currentCount++;
                string targetName = ConvertorGeneratorHelper.GetCurrentKey(mappingOrders, currentCount, keyList).Replace("_", "");
                if (string.IsNullOrEmpty(targetName))
                {
                    continue;
                }
                string sourceName = distToSrc[targetName].Replace("_","");
                if (MemberGetterGenerator.ContainsMember(sourceName, inputType, inputObject) && MemberSetterGenerator.ContainsMember(targetName, outputType, outputObject))
                {
                    Type targetType = ConvertorGeneratorHelper.GetMemberType(members[targetName]);

                    LocalBuilder memberValue = gen.DeclareLocal(targetType, "memberValue");

                    MemberGetterGenerator.GetMemberValue(gen, inputObjectArg, sourceName, ref memberValue);

                    MemberSetterGenerator.SetMemberValue(gen, outputObjectArg, targetName, memberValue);
                }
            }
            gen.Ldarg(outputObjectArg);
            MemberSetterGenerator.EndSetMembers(gen, outputObjectArg);
            return (ConvertHandler)gen.EndMethod();
        }
Пример #5
0
        public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue)
        {
            LocalBuilder tempLocal = generator.DeclareLocal(typeof(object), "dataColumn");
            Type targetType = memberValue.LocalType;
            Type originalType = ConvertorGeneratorHelper.GetOriginalType(targetType);

            generator.Ldarg(targetObject);
            generator.Load(memberName);
            generator.Call(typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(string) }));
            generator.Stloc(tempLocal);

            generator.Ldloc(tempLocal);
            generator.LoadMember(typeof(DBNull).GetField("Value", BindingFlags.Static | BindingFlags.Public));
            generator.If(Cmp.EqualTo);
            generator.LoadDefaultValue(targetType);
            generator.Stloc(memberValue);
            generator.Else();
            generator.Ldloc(tempLocal);

            generator.InternalILGenerator.Emit(OpCodes.Isinst, targetType);
            generator.InternalILGenerator.Emit(OpCodes.Ldnull);
            generator.InternalILGenerator.Emit(OpCodes.Cgt_Un);
            generator.Load(true);
            generator.If(Cmp.EqualTo);
            generator.Ldloc(tempLocal);
            if (targetType.IsValueType)
            {
                generator.UnboxAny(targetType);
            }
            generator.Stloc(memberValue);
            generator.Else();
            if (targetType == typeof(Guid))
            {
                generator.Ldloc(tempLocal);
                generator.InternalILGenerator.Emit(OpCodes.Isinst, typeof(string));
                generator.InternalILGenerator.Emit(OpCodes.Ldnull);
                generator.InternalILGenerator.Emit(OpCodes.Cgt_Un);
                generator.Load(true);
                generator.If(Cmp.EqualTo);
                generator.Ldloc(tempLocal);
                generator.New(typeof(Guid).GetConstructor(new Type[] { typeof(string) }));
                generator.Stloc(memberValue);
            }
            else
            {
                generator.Ldloc(tempLocal);
                generator.InternalILGenerator.Emit(OpCodes.Isinst, typeof(IConvertible));
                generator.InternalILGenerator.Emit(OpCodes.Ldnull);
                generator.InternalILGenerator.Emit(OpCodes.Cgt_Un);
                generator.Load(true);
                generator.If(Cmp.EqualTo);
                generator.Ldloc(tempLocal);
                generator.Load(originalType);
                generator.Call(typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) }));
                if (targetType.IsValueType)
                {
                    generator.UnboxAny(targetType);
                }
                generator.Stloc(memberValue);
            }
            generator.Else();
            generator.LoadDefaultValue(targetType);
            generator.Stloc(memberValue);
            generator.EndIf();
            generator.EndIf();
            generator.EndIf();
        }
Пример #6
0
        public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue)
        {
            MethodInfo getMethod;
            bool mustBeUnBox = false;

            switch (Type.GetTypeCode(memberValue.LocalType))
            {
                case TypeCode.Boolean:
                    getMethod = typeof(IDataRecord).GetMethod("GetBoolean");
                    break;
                case TypeCode.Byte:
                    getMethod = typeof(IDataRecord).GetMethod("GetByte");
                    break;
                case TypeCode.Char:
                    getMethod = typeof(IDataRecord).GetMethod("GetChar");
                    break;
                case TypeCode.DateTime:
                    getMethod = typeof(IDataRecord).GetMethod("GetDateTime");
                    break;
                case TypeCode.Decimal:
                    getMethod = typeof(IDataRecord).GetMethod("GetDecimal");
                    break;
                //Teddy 2008-2-2: commented the lines below, because for some database, return data type of float or real could always be System.Single or System.Double
                //case TypeCode.Double:
                //    getMethod = typeof(IDataRecord).GetMethod("GetDouble");
                //    break;
                //case TypeCode.Single:
                //    getMethod = typeof(IDataRecord).GetMethod("GetFloat");
                //    break;
                case TypeCode.Int16:
                    getMethod = typeof(IDataRecord).GetMethod("GetInt16");
                    break;
                case TypeCode.Int32:
                    getMethod = typeof(IDataRecord).GetMethod("GetInt32");
                    break;
                case TypeCode.Int64:
                    getMethod = typeof(IDataRecord).GetMethod("GetInt64");
                    break;
                case TypeCode.String:
                    getMethod = typeof(IDataRecord).GetMethod("GetString");
                    break;
                default:
                    getMethod = typeof(IDataRecord).GetMethod("GetValue");
                    mustBeUnBox = true;
                    break;
            }
            if (memberValue.LocalType == typeof(Guid))
            {
                getMethod = typeof(IDataRecord).GetMethod("GetGuid");
                mustBeUnBox = false;
            }
            if (memberValue.LocalType.IsEnum)
            {
                getMethod = typeof(IDataRecord).GetMethod("GetValue");
                mustBeUnBox = true;
            }

            generator.Ldarg(targetObject);
            generator.Load(memberName);
            generator.Call(typeof(IDataRecord).GetMethod("GetOrdinal"));
            LocalBuilder fieldOrdinalLoc = generator.DeclareLocal(typeof(int));
            generator.Stloc(fieldOrdinalLoc);
            generator.Ldarg(targetObject);
            generator.Ldloc(fieldOrdinalLoc);
            generator.Call(typeof(IDataRecord).GetMethod("IsDBNull"));
            generator.IfNot();
            generator.Ldarg(targetObject);
            generator.Ldloc(fieldOrdinalLoc);
            generator.Call(getMethod);

            //Teddy 2008-2-2: added the  code section below to convert the object to the memberValue.LocalType
            if (!memberValue.LocalType.IsEnum && getMethod == typeof(IDataRecord).GetMethod("GetValue"))
            {
                generator.Load(Type.GetTypeCode(memberValue.LocalType));
                generator.Call(typeof(Convert).GetMethod("ChangeType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(object), typeof(TypeCode) }, null));
            }

            if (memberValue.LocalType.IsValueType && mustBeUnBox)
            {
                generator.UnboxAny(memberValue.LocalType);
            }
            generator.Else();
            generator.LoadDefaultValue(memberValue.LocalType);
            generator.EndIf();
            generator.Stloc(memberValue);
        }