Example #1
0
        public static void GenerateDeserializeWithIDictionaryEmptyCtor()
        {
            /*
             * var map = MapFormatterHelper.Deserialize(ref reader,ref context);
             * if (map == null)
             *    return null;
             * context.option.Security.DepthStep(ref reader);
             * T t = new T();
             * Deserialize(IEnumerable<KeyValuePair<TKey, TValue>> pair,(ICollection<KeyValuePair<TKey, TValue>>)t);
             * reader = map.Reader; context = map.Context;
             * reader.Seek(map.EndPos);
             * context.Depth--;
             * return t;
             */

            ArrayPack <Expression> ary       = new ArrayPack <Expression>(10);
            Type                t            = typeof(T);
            LabelTarget         returnTarget = Expression.Label(t, "returnLable");
            ParameterExpression map          = Expression.Variable(typeof(IMapDataSource <,>).MakeGenericType(typeof(object), typeof(object)));

            //map = MapFormatterHelper.Deserialize(ref reader,ref context);
            ary.Add(Expression.Assign(map, CommonExpressionMeta.Call_MapFormatterHelper_Deserialize(typeof(object), typeof(object))));
            //if (map == null)
            //      goto label;
            ary.Add(Expression.IfThen(Expression.Equal(map, Expression.Constant(null, map.Type)), Expression.Return(returnTarget, Expression.Default(t))));
            //context.option.Security.DepthStep(ref reader);
            ary.Add(CommonExpressionMeta.Call_DeserializeContext_Option_Security_DepthStep);
            //T t = new T();
            ParameterExpression instance = Expression.Variable(t);

            ary.Add(Expression.Assign(instance, Expression.New(t)));
            //MapFormatterHelper.FillData(map,(IDictionary)t)
            ary.Add(Expression.Call(null, typeof(MapFormatterHelper).GetMethod(nameof(MapFormatterHelper.FillIDictionaryData), BindingFlags.Public | BindingFlags.Static), map, Expression.Convert(instance, typeof(IDictionary))));

            //reader = map.Reader; context = map.Context;
            ary.Add(CommonExpressionMeta.Block_MapReaderAndContextAssignLocalReaderAndContext(map));
            //reader.Seek(map.EndPos);
            ary.Add(CommonExpressionMeta.Call_Reader_BufferSeek(Expression.Property(map, nameof(IMapDataSource <int, int> .EndPosition))));
            //context.Depth--;
            ary.Add(CommonExpressionMeta.Call_DeserializeContext_Depth_DecrementAssign);
            //return t;
            ary.Add(Expression.Return(returnTarget, instance));
            //label default(T)
            ary.Add(Expression.Label(returnTarget, instance));

            BlockExpression block = Expression.Block(new ParameterExpression[] { map, instance }, ary.GetArray());

            Deserialize = Expression.Lambda <Deserialize <T> >(block, CommonExpressionMeta.Par_Reader, CommonExpressionMeta.Par_DeserializeContext).Compile();
        }
        private static Expression BuildDeserializeCore(Type t, ObjectSerializationInfo serializationInfo)
        {
            List <Expression> ary          = new List <Expression>();
            LabelTarget       returnTarget = Expression.Label(t, "returnLable");
            //int num;
            ParameterExpression num = Expression.Variable(typeof(int), "num");
            //int for-i;
            ParameterExpression forVariable = Expression.Variable(typeof(int), "i");

            //context.option.Security.DepthStep(ref reader);
            ary.Add(CommonExpressionMeta.Call_DeserializeContext_Option_Security_DepthStep);

            //if(reader.TryReadNullWithEnsureBuildInType(BssomType.Array3))
            //      return default(t);
            ary.Add(Expression.IfThen(CommonExpressionMeta.Call_Reader_TryReadNullWithEnsureBuildInType(BssomType.Array3),
                                      Expression.Return(returnTarget, Expression.Default(t))));

            //T t = new T();
            ParameterExpression instance = Expression.Parameter(t, "instance");

            if (serializationInfo.IsDefaultNoArgsCtor)
            {
                ary.Add(Expression.Assign(instance, Expression.New(t)));
            }
            else
            {
                ParameterInfo[] parInfos = serializationInfo.BestmatchConstructor.GetParameters();
                Expression[]    pars     = new Expression[parInfos.Length];
                if (serializationInfo.ConstructorParametersIsDefaultValue)
                {
                    for (int i = 0; i < parInfos.Length; i++)
                    {
                        pars[i] = Expression.Default(parInfos[i].ParameterType);
                    }
                    ary.Add(Expression.Assign(instance, Expression.New(serializationInfo.BestmatchConstructor, pars)));
                }
                else
                {
                    object[] cps = serializationInfo.ConstructorParameters;
                    for (int i = 0; i < parInfos.Length; i++)
                    {
                        pars[i] = Expression.Constant(cps[i], parInfos[i].ParameterType);
                    }
                    ary.Add(Expression.Assign(instance, Expression.New(serializationInfo.BestmatchConstructor, pars)));
                }
            }

            //reader.SkipVariableNumber()
            ary.Add(CommonExpressionMeta.Call_Reader_SkipVariableNumber);
            //num = reader.ReadVariableNumber()
            ary.Add(Expression.Assign(num, CommonExpressionMeta.Call_Reader_ReadVariableNumber));
            //i = 0;
            ary.Add(Expression.Assign(forVariable, Expression.Constant(0)));

            var members = serializationInfo.SerializeMemberInfos;

            if (members.Length > 0)
            {
                //reader.Buffer.Seek(offsetSegment, Current)
                ary.Add(CommonExpressionMeta.Call_Reader_BufferSeek(Expression.Convert(Expression.Multiply(num, Expression.Constant(BssomBinaryPrimitives.FixUInt32NumberSize)), typeof(Int64)), BssomSeekOrgin.Current));
                //switch(i)
                //  case 0: instance.Key0 = readValue();
                //  case 3: instance.Key1 = readValue();
                //  case 5: instance.Key2 = readValue();
                //  default: skipObj();
                FieldInfo    memFormatters = serializationInfo.StoreMemberFormatterInstances();
                SwitchCase[] switchCases   = new SwitchCase[members.Length];
                for (int i = 0; i < members.Length; i++)
                {
                    switchCases[i] = Expression.SwitchCase(SpecialCodeGenExpression.ReadValues(members[i], instance, memFormatters), Expression.Constant(members[i].KeyIndex));
                }
                Expression content = Expression.Switch(
                    typeof(void),
                    forVariable,
                    CommonExpressionMeta.Call_Reader_SkipObject,
                    null,
                    switchCases
                    );

                ary.Add(For(forVariable, Expression.LessThan(forVariable, num), Expression.Assign(forVariable, Expression.Add(forVariable, Expression.Constant(1))), content));
            }
            //context.Depth--;
            ary.Add(CommonExpressionMeta.Call_DeserializeContext_Depth_DecrementAssign);

            ary.Add(Expression.Return(returnTarget, instance));

            ary.Add(Expression.Label(returnTarget, instance));

            return(Expression.Block(new ParameterExpression[] { instance, num, forVariable, }, ary));
        }