private static System.Delegate CreateTypeDeserializer(Type type) { var expressions = new List <Expression>(); var variables = new List <ParameterExpression>(); var inputStream = Expression.Parameter(typeof(Stream), "inputStream"); var objTracker = Expression.Parameter(typeof(DeserializerObjectTracker), "objTracker"); var returnValue = Expression.Parameter(type, "retVal"); variables.Add(returnValue); var primitiveReader = GetPrimitiveReader(type); if (primitiveReader != null) { expressions.Add(Expression.Assign(returnValue, Expression.Convert(primitiveReader(inputStream, objTracker), type))); } else if (type == typeof(string)) { expressions.Add(Expression.Assign(returnValue, GenerateStringExpression(inputStream, objTracker))); } else if (InternalSerializationStuff.ImplementsISerializableWithSerializationConstructor(type)) { expressions.Add(Expression.Assign(returnValue, ISerializableDeserializer.GenerateISerializableExpression(type, variables, inputStream, objTracker))); } else if (InternalSerializationStuff.ImplementsDictionaryGeneric(type)) { expressions.Add(Expression.Assign(returnValue, DictionaryDeserializer.GenerateDictionaryGenericExpression(type, variables, inputStream, objTracker))); } else if (type.IsArray) { expressions.Add(Expression.Assign(returnValue, GenerateArrayExpression(type, inputStream, objTracker))); } else if (type == typeof(ExpandoObject)) { expressions.Add(Expression.Assign(returnValue, ExpandoDeserializer.GenerateExpandoObjectExpression(variables, inputStream, objTracker))); } else { expressions.Add(Expression.Assign(returnValue, GenerateClassExpression(type, inputStream, objTracker))); } expressions.Add(returnValue); var block = Expression.Block(variables, expressions); var f = typeof(Func <, ,>).MakeGenericType(typeof(Stream), typeof(DeserializerObjectTracker), type); return(Expression.Lambda(f, block, inputStream, objTracker).Compile()); }
private static Expression DeserializeDictionary(Type type, List <ParameterExpression> variables, ParameterExpression inputStream, ParameterExpression objTracker, ParameterExpression newInstance) { var notTrackedExpressions = new List <Expression>(); notTrackedExpressions.Add(Expression.Assign(newInstance, Expression.New(type.GetConstructor(new Type[0])))); notTrackedExpressions.Add(Expression.Call(objTracker, DeserializerObjectTrackerMih.TrackedObject(), newInstance)); notTrackedExpressions.AddRange(DictionaryDeserializer.DeserializeDictionaryValues(type, variables, inputStream, objTracker, newInstance)); return(Expression.Block(notTrackedExpressions)); }
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)); }