private static Func <EnumerableLoopBodyCargo, Expression> GetLoopBodyCargo(ParameterExpression siClone, ParameterExpression clonedItem, ParameterExpression refTrackerParam) { Func <EnumerableLoopBodyCargo, Expression> loopBody = cargo => { var keyExpression = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetProperty("Current")), cargo.KvpType.GetProperty("Name")); var valueExpression = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetProperty("Current")), cargo.KvpType.GetProperty("Value")); var cloneValueExpr = Expression.Block(ClassCloner.GetCloneClassTypeExpression(refTrackerParam, valueExpression, clonedItem, typeof(object)), Expression.Call(siClone, SerializationInfoMih.AddValue(), keyExpression, clonedItem)); return(Expression.IfThenElse(Expression.Equal(valueExpression, Expression.Constant(null)), Expression.Call(siClone, SerializationInfoMih.AddValue(), keyExpression, Expression.Constant((object)null, typeof(object))), cloneValueExpr)); }; return(loopBody); }
private static Expression DeserializeISerializable(Type type, List <ParameterExpression> variables, ParameterExpression inputStream, ParameterExpression objTracker, ParameterExpression newInstance) { var length = Expression.Parameter(typeof(int), "length"); var i = Expression.Parameter(typeof(int), "i"); var key = Expression.Parameter(typeof(string), "key"); var value = Expression.Parameter(typeof(object), "value"); var typeName = Expression.Parameter(typeof(string), "typeName"); var typeExpr = Expression.Parameter(typeof(TypeWithHashCode), "type"); var deserializer = Expression.Parameter(typeof(Func <Stream, DeserializerObjectTracker, object>), "deserializer"); var typeHashCode = Expression.Parameter(typeof(int), "typeHashCode"); var fc = Expression.Parameter(typeof(FormatterConverter), "fc"); var context = Expression.Parameter(typeof(StreamingContext), "context"); var si = Expression.Parameter(typeof(SerializationInfo), "si"); variables.Add(fc); variables.Add(context); variables.Add(si); variables.Add(key); variables.Add(value); variables.Add(length); variables.Add(i); variables.Add(deserializer); variables.Add(typeName); variables.Add(typeExpr); variables.Add(typeHashCode); var loopExpressions = new List <Expression>(); DictionaryDeserializer.GetReadExpression(inputStream, objTracker, typeof(string), loopExpressions, key, typeExpr, typeName, typeHashCode, deserializer); DictionaryDeserializer.GetReadExpression(inputStream, objTracker, typeof(object), loopExpressions, value, typeExpr, typeName, typeHashCode, deserializer); loopExpressions.Add(Expression.Call(si, SerializationInfoMih.AddValue(), key, value)); loopExpressions.Add(Expression.Assign(i, Expression.Add(i, Expression.Constant(1)))); var cond = Expression.LessThan(i, length); var loopBody = Expression.Block(loopExpressions); var breakLabel = Expression.Label("breakLabel"); var loop = Expression.Loop(Expression.IfThenElse(cond, loopBody, Expression.Break(breakLabel)), breakLabel); var notTrackedExpressions = new List <Expression>(); notTrackedExpressions.Add(Expression.Assign(fc, Expression.New(typeof(FormatterConverter)))); notTrackedExpressions.Add(Expression.Assign(context, Expression.New(StreamingContextMih.Constructor(), Expression.Constant(StreamingContextStates.All)))); notTrackedExpressions.Add(Expression.Assign(si, Expression.New(SerializationInfoMih.Constructor(), Expression.Constant(type), fc))); notTrackedExpressions.Add(Expression.Assign(length, PrimitiveHelpers.ReadInt32(inputStream, objTracker))); notTrackedExpressions.Add(Expression.Assign(i, Expression.Constant(0))); notTrackedExpressions.Add(loop); notTrackedExpressions.Add(Expression.Assign(newInstance, Expression.New(ISerializableSerializer.GetSerializationConstructor(type), si, context))); if (type.IsClass) { notTrackedExpressions.Add(Expression.Call(objTracker, DeserializerObjectTrackerMih.TrackedObject(), newInstance)); } notTrackedExpressions.AddRange(SerializationCallbacksHelper.GenerateOnDeserializedAttributeExpression(type, newInstance, context)); notTrackedExpressions.Add(SerializationCallbacksHelper.GenerateCallIDeserializationExpression(type, newInstance)); notTrackedExpressions.Add(newInstance); return(Expression.Block(notTrackedExpressions)); }