internal static void GetReadExpression(ParameterExpression inputStream, ParameterExpression objTracking, Type expectedType, List <Expression> loopExpressions, ParameterExpression tmpVariable, ParameterExpression typeExpr, ParameterExpression typeName, ParameterExpression typeHashCode, ParameterExpression deserializer) { if (expectedType == typeof(string)) { loopExpressions.Add(Expression.Assign(tmpVariable, Deserializer.GenerateStringExpression(inputStream, objTracking))); } else if (expectedType.IsPrimitive || expectedType.IsValueType) { var primitiveDeserializer = Deserializer.GetTypeDeserializer(expectedType); loopExpressions.Add(Expression.Assign(tmpVariable, Expression.Convert(Expression.Invoke(Expression.Constant(primitiveDeserializer), inputStream, objTracking), expectedType))); } else { loopExpressions.Add(Deserializer.GetReadClassExpression(inputStream, objTracking, tmpVariable, typeExpr, typeName, typeHashCode, deserializer, expectedType)); } }
private static IEnumerable <Expression> ReadDimensionalArray(Type type, Type elementType, ParameterExpression newInstance, List <ParameterExpression> variables, ParameterExpression inputStream, ParameterExpression lengths, ParameterExpression objTracker, int rank) { var typeName = Expression.Parameter(typeof(string), "typeName"); var typeExpr = Expression.Parameter(typeof(TypeWithHashCode), "type"); var indices = Expression.Parameter(typeof(int[]), "indices"); var tmpValue = Expression.Parameter(elementType, "tmpValue"); var deserializer = Expression.Parameter(typeof(Func <Stream, DeserializerObjectTracker, object>), "deserializer"); var typeHashCode = Expression.Parameter(typeof(int), "typeHashCode"); variables.Add(deserializer); variables.Add(typeName); variables.Add(typeExpr); variables.Add(tmpValue); variables.Add(typeHashCode); var expressions = new List <Expression>(); expressions.Add(Expression.Assign(newInstance, Expression.Convert(Expression.Call(ArrayMih.CreateInstance(), Expression.Constant(elementType), lengths), type))); if (type.IsClass) { expressions.Add(Expression.Call(objTracker, DeserializerObjectTrackerMih.TrackedObject(), newInstance)); } if (rank > 1) { variables.Add(indices); expressions.Add(Expression.Assign(indices, Expression.Call(CreateArrayMethodInfo.GetCreateArrayMethodInfo(typeof(int)), Expression.Property(lengths, "Length")))); } Expression innerExpression; if (elementType == typeof(string)) { innerExpression = Expression.Assign(tmpValue, Deserializer.GenerateStringExpression(inputStream, objTracker)); } else if (elementType.IsPrimitive || elementType.IsValueType) { var primitiveReader = Deserializer.GetPrimitiveReader(elementType); if (primitiveReader == null) { var primitiveDeserializer = Deserializer.GetTypeDeserializer(elementType); innerExpression = Expression.Assign(tmpValue, Expression.Convert(Expression.Invoke(Expression.Constant(primitiveDeserializer), inputStream, objTracker), elementType)); } else { if (elementType == typeof(byte) || elementType == typeof(sbyte) || elementType == typeof(byte?) || elementType == typeof(sbyte?) || Deserializer.IsEnumOrNullableEnum(elementType)) { innerExpression = Expression.Assign(tmpValue, Expression.Convert(primitiveReader(inputStream, objTracker), elementType)); } else { innerExpression = Expression.Assign(tmpValue, primitiveReader(inputStream, objTracker)); } } } else { innerExpression = Deserializer.GetReadClassExpression(inputStream, objTracker, tmpValue, typeExpr, typeName, typeHashCode, deserializer, elementType); } Func <int, Expression, Expression> readArrayLoop = (loopRank, innerExpr) => { var loopRankIndex = Expression.Parameter(typeof(int), "loopRankIndex" + loopRank); variables.Add(loopRankIndex); var loopExpressions = new List <Expression>(); if (rank == 1) { loopExpressions.Add(innerExpr); loopExpressions.Add(Expression.Assign(Expression.ArrayAccess(newInstance, loopRankIndex), tmpValue)); } else { loopExpressions.Add(Expression.Assign(Expression.ArrayAccess(indices, Expression.Constant(loopRank)), loopRankIndex)); loopExpressions.Add(innerExpr); loopExpressions.Add(Expression.Call(newInstance, ArrayMih.SetValueRank(), Expression.Convert(tmpValue, typeof(object)), indices)); } loopExpressions.Add(Expression.Assign(loopRankIndex, Expression.Add(loopRankIndex, Expression.Constant(1)))); var cond = Expression.LessThan(loopRankIndex, Expression.ArrayIndex(lengths, Expression.Constant(loopRank))); var loopBody = Expression.Block(loopExpressions); var breakLabel = Expression.Label("breakLabel" + loopRank); var loop = Expression.Loop(Expression.IfThenElse(cond, loopBody, Expression.Break(breakLabel)), breakLabel); return(Expression.Block(Expression.Assign(loopRankIndex, Expression.Constant(0)), loop)); }; for (int r = rank - 1; r >= 0; r--) { innerExpression = readArrayLoop(r, innerExpression); } expressions.Add(innerExpression); return(expressions); }