private static Func <EnumerableLoopBodyCargo, Expression> CloneKeyValuePair(ParameterExpression clone, ParameterExpression refTrackerParam) { Func <EnumerableLoopBodyCargo, Expression> loopBody = cargo => { var keyExpression = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetTypeInfo().GetDeclaredProperty("Current")), cargo.KvpType.GetTypeInfo().GetDeclaredProperty("Key")); var valueExpression = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetTypeInfo().GetDeclaredProperty("Current")), cargo.KvpType.GetTypeInfo().GetDeclaredProperty("Value")); var addExpr = Expression.Call(clone, DictionaryMih.Add <string, object>(), keyExpression, ClassCloner.CallCopyExpression(valueExpression, refTrackerParam, Expression.Call(valueExpression, ObjectMih.GetTypeMethod()))); var addNullExpr = Expression.Call(clone, DictionaryMih.Add <string, object>(), keyExpression, Expression.Constant(null)); return(Expression.IfThenElse(Expression.NotEqual(valueExpression, Expression.Constant(null)), addExpr, addNullExpr)); }; return(loopBody); }
internal static List <Expression> DeserializeDictionaryValues(Type type, List <ParameterExpression> variables, ParameterExpression inputStream, ParameterExpression objTracker, ParameterExpression newInstance) { var dictionaryType = DictionaryHelper.GetDictionaryType(type); var keyType = dictionaryType.GetGenericArguments()[0]; var valueType = dictionaryType.GetGenericArguments()[1]; var i = Expression.Parameter(typeof(int), "i"); var length = Expression.Parameter(typeof(int), "length"); var key = Expression.Parameter(keyType, "key"); var value = Expression.Parameter(dictionaryType.GetGenericArguments()[1], "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"); variables.Add(i); variables.Add(length); variables.Add(key); variables.Add(value); variables.Add(typeName); variables.Add(typeExpr); variables.Add(deserializer); variables.Add(typeHashCode); var loopExpressions = new List <Expression>(); GetReadExpression(inputStream, objTracker, keyType, loopExpressions, key, typeExpr, typeName, typeHashCode, deserializer); GetReadExpression(inputStream, objTracker, valueType, loopExpressions, value, typeExpr, typeName, typeHashCode, deserializer); loopExpressions.Add(Expression.Call(newInstance, DictionaryMih.Add(dictionaryType, keyType, dictionaryType.GetGenericArguments()[1]), 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(length, PrimitiveHelpers.ReadInt32(inputStream, objTracker))); notTrackedExpressions.Add(Expression.Assign(i, Expression.Constant(0))); notTrackedExpressions.Add(loop); notTrackedExpressions.Add(newInstance); return(notTrackedExpressions); }
public static Expression GenerateDictionaryGenericExpression(List <ParameterExpression> variables, ParameterExpression source, ParameterExpression clone, Type sourceType, ParameterExpression refTrackerParam) { var ctor = sourceType.GetConstructor(new Type[0]); if (ctor == null) { throw new MissingConstructorException("Type " + sourceType + " must have a public constructor without parameter."); } var genericDictionaryType = DictionaryHelper.GetDictionaryType(sourceType); var comparerConstructor = DictionaryHelper.GetComparerConstructor(sourceType); var cloneDictionaryWithDefaultComparer = CloneDictionaryWithDefaultComparer(genericDictionaryType, variables, source, clone, sourceType, refTrackerParam); if (comparerConstructor == null) { return(cloneDictionaryWithDefaultComparer); } return(Expression.IfThenElse(Expression.IsTrue(Expression.Call(DictionaryMih.IsDefaultEqualityComparer(), Expression.Constant(genericDictionaryType.GetGenericArguments()[0]), Expression.Property(source, nameof(Dictionary <int, int> .Comparer)))), cloneDictionaryWithDefaultComparer, CloneDictionaryWithCustomComparer(genericDictionaryType, comparerConstructor, variables, source, clone, sourceType, refTrackerParam))); }
/// <summary> /// Generates an expression tree to deserialize an ExpandoObject /// </summary> /// <param name="variables">Global variables for the expression tree</param> /// <param name="inputStream">Stream to read from</param> /// <param name="objTracker">Reference tracker</param> /// <returns>An expression tree to deserialize an ExpandoObject</returns> internal static Expression GenerateExpandoObjectExpression(List <ParameterExpression> variables, ParameterExpression inputStream, ParameterExpression objTracker) { var dictType = typeof(IDictionary <string, object>); 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 newInstance = Expression.Parameter(typeof(ExpandoObject), "newInstance"); var destDict = Expression.Parameter(dictType, "destDict"); var typeHashCode = Expression.Parameter(typeof(int), "typeHashCode"); var trackType = Expression.Parameter(typeof(byte), "trackType"); variables.Add(key); variables.Add(value); variables.Add(length); variables.Add(i); variables.Add(deserializer); variables.Add(typeName); variables.Add(typeExpr); variables.Add(newInstance); variables.Add(destDict); variables.Add(typeHashCode); variables.Add(trackType); var loopExpressions = new List <Expression>(); loopExpressions.Add(Expression.Assign(key, Deserializer.GenerateStringExpression(inputStream, objTracker))); loopExpressions.Add(Deserializer.GetReadClassExpression(inputStream, objTracker, value, typeExpr, typeName, typeHashCode, deserializer, typeof(object))); loopExpressions.Add(Expression.Call(destDict, DictionaryMih.Add <string, object>(), 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(length, PrimitiveHelpers.ReadInt32(inputStream, objTracker))); notTrackedExpressions.Add(Expression.Assign(i, Expression.Constant(0))); notTrackedExpressions.Add(Expression.Assign(newInstance, Expression.New(typeof(ExpandoObject)))); notTrackedExpressions.Add(Expression.Assign(destDict, Expression.Convert(newInstance, dictType))); notTrackedExpressions.Add(Expression.Call(objTracker, DeserializerObjectTrackerMih.TrackedObject(), newInstance)); notTrackedExpressions.Add(loop); return(Deserializer.GenerateNullTrackedOrUntrackedExpression(typeof(ExpandoObject), inputStream, objTracker, newInstance, notTrackedExpressions, trackType, variables)); }
/// <summary> /// Generates an expression tree to handle ISerializable serialization /// </summary> /// <param name="type">Type of the object to serialize</param> /// <param name="variables">Global variables for the expression tree</param> /// <param name="outputStream">Stream to write to</param> /// <param name="objToSerialize">Object to serialize</param> /// <param name="objTracking">Reference tracker</param> /// <returns>An expression tree to handle ISerializable serialization</returns> public static Expression GenerateISerializableExpression(Type type, List <ParameterExpression> variables, ParameterExpression outputStream, ParameterExpression objToSerialize, ParameterExpression objTracking) { if (GetSerializationConstructor(type) == null) { throw new MissingConstructorException("Cannot serialize type " + type + " because it does not have the required constructor for ISerializable. If you inherits from a class that implements ISerializable you have to expose the serialization constructor."); } var dictionaryType = DictionaryHelper.GetDictionaryType(type, throwIfNotADictionary: false); var notTrackedExpressions = new List <Expression>(); if (dictionaryType == null) { notTrackedExpressions.Add(SerializeISerializable(type, variables, outputStream, objToSerialize, objTracking)); } else { notTrackedExpressions.Add(Expression.IfThenElse(Expression.IsTrue(Expression.Call(DictionaryMih.IsObjectADictionaryWithDefaultComparerAndNoAdditionalProperties(), objToSerialize)), DictionarySerializer.SerializeDictionary(type, dictionaryType, variables, outputStream, objToSerialize, objTracking, true), SerializeISerializable(type, variables, outputStream, objToSerialize, objTracking))); } return(Serializer.GenerateNullTrackedOrUntrackedExpression(type, outputStream, objToSerialize, objTracking, notTrackedExpressions, variables)); }
public static Expression GenerateDictionaryGenericExpression(Type type, List <ParameterExpression> variables, ParameterExpression outputStream, ParameterExpression objToSerialize, ParameterExpression objTracking) { var ctor = type.GetConstructor(new Type[0]); if (ctor == null) { throw new MissingConstructorException("Type " + type + " must have a public constructor without parameter."); } var notTrackedExpressions = new List <Expression>(); var genericDictionaryType = DictionaryHelper.GetDictionaryType(type); var comparerConstructor = DictionaryHelper.GetComparerConstructor(type); var serializeDictionaryWithDefaultComparer = SerializeDictionaryWithDefaultComparer(genericDictionaryType, variables, type, outputStream, objToSerialize, objTracking); if (comparerConstructor == null) { notTrackedExpressions.Add(serializeDictionaryWithDefaultComparer); } else { notTrackedExpressions.Add(Expression.IfThenElse(Expression.IsTrue(Expression.Call(DictionaryMih.IsDefaultEqualityComparer(), Expression.Constant(genericDictionaryType.GetGenericArguments()[0]), Expression.Property(objToSerialize, nameof(Dictionary <int, int> .Comparer)))), serializeDictionaryWithDefaultComparer, SerializeDictionaryWithCustomComparer(genericDictionaryType, variables, type, outputStream, objToSerialize, objTracking))); } return(Serializer.GenerateNullTrackedOrUntrackedExpression(type, outputStream, objToSerialize, objTracking, notTrackedExpressions, variables)); }