Example #1
0
 Func <BasePackable, Type, Stream, object> GetReadFunc(Type type)
 {
     if (ReadFuncs.ContainsKey(type))
     {
         return(ReadFuncs[type]);
     }
     foreach (var t in type.GetInterfaces())
     {
         if (UnpackInterfaces.ContainsKey(t))
         {
             return(UnpackInterfaces[t]);
         }
     }
     throw new NotSupportedException();
 }
Example #2
0
            public Action <object, Stream> CreateRead(Type type)
            {
                var members = GetMembers(type);
                var ret     = new DynamicMethod("Read_" + 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 (!ReadFuncs.ContainsKey(mtype))
                    {
                        throw new NotSupportedException();
                    }

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

                    if (!mtype.IsValueType)
                    {
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Call, ReadFuncs[typeof(byte)].Method);
                        il.Emit(OpCodes.Unbox_Any, typeof(byte));
                        il.Emit(OpCodes.Brtrue, ifnotnull);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Castclass, type);
                        il.Emit(OpCodes.Ldnull);
                        if (m is FieldInfo)
                        {
                            il.Emit(OpCodes.Stfld, f);
                        }
                        else if (m is PropertyInfo)
                        {
                            il.Emit(OpCodes.Call, p.GetSetMethod());
                        }
                        il.Emit(OpCodes.Br, ifnull);
                    }

                    il.MarkLabel(ifnotnull);

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Castclass, type);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Call, ReadFuncs[mtype].Method);

                    if (mtype.IsValueType)
                    {
                        il.Emit(OpCodes.Unbox_Any, mtype);
                    }
                    else
                    {
                        il.Emit(OpCodes.Castclass, mtype);
                    }

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

                    il.MarkLabel(ifnull);
                }
                il.Emit(OpCodes.Ret);
                return((Action <object, Stream>)ret.CreateDelegate(typeof(Action <object, Stream>)));
            }