Пример #1
0
 Action <BasePackable, Type, Stream, object> GetWriteFunc(Type type)
 {
     if (WriteFuncs.ContainsKey(type))
     {
         return(WriteFuncs[type]);
     }
     foreach (var t in type.GetInterfaces())
     {
         if (PackInterfaces.ContainsKey(t))
         {
             return(PackInterfaces[t]);
         }
     }
     throw new NotSupportedException();
 }
Пример #2
0
            public Action <object, Stream> CreateWrite(Type type)
            {
                var members = GetMembers(type);
                var ret     = new DynamicMethod("Write_" + type.MetadataToken, null, new Type[] { typeof(object), typeof(Stream) });
                var il      = ret.GetILGenerator();

                foreach (MemberInfo m in members)
                {
                    var f = m as FieldInfo;
                    var p = m as PropertyInfo;

                    Type mtype = null;
                    if (m is FieldInfo)
                    {
                        mtype = f.FieldType;
                    }
                    else if (m is PropertyInfo)
                    {
                        mtype = p.PropertyType;
                    }

                    if (!WriteFuncs.ContainsKey(mtype))
                    {
                        throw new NotSupportedException();
                    }

                    var ifnotnull = il.DefineLabel();
                    var ifnull    = il.DefineLabel();

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Castclass, type);

                    if (m is FieldInfo)
                    {
                        il.Emit(OpCodes.Ldfld, f);
                    }
                    else if (m is PropertyInfo)
                    {
                        il.Emit(OpCodes.Call, p.GetGetMethod());
                    }

                    if (!mtype.IsValueType)
                    {
                        il.Emit(OpCodes.Dup);
                        il.Emit(OpCodes.Brtrue, ifnotnull);
                        il.Emit(OpCodes.Ldc_I4_0);
                        il.Emit(OpCodes.Box, typeof(byte));
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Call, WriteFuncs[typeof(byte)].Method);
                        il.Emit(OpCodes.Pop);
                        il.Emit(OpCodes.Br, ifnull);
                        il.MarkLabel(ifnotnull);
                        il.Emit(OpCodes.Ldc_I4_1);
                        il.Emit(OpCodes.Box, typeof(byte));
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Call, WriteFuncs[typeof(byte)].Method);
                    }

                    if (mtype.IsValueType)
                    {
                        il.Emit(OpCodes.Box, mtype);
                    }

                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Call, WriteFuncs[mtype].Method);
                    il.MarkLabel(ifnull);
                }
                il.Emit(OpCodes.Ret);
                return((Action <object, Stream>)ret.CreateDelegate(typeof(Action <object, Stream>)));
            }