Example #1
0
        /// <summary>
        /// Generates an expression tree to handle ISerializable deserialization
        /// </summary>
        /// <param name="type">Type to deserialize</param>
        /// <param name="variables">Global variables for expression tree</param>
        /// <param name="inputStream">Stream to read from</param>
        /// <param name="objTracker">Reference tracker</param>
        /// <returns>An expression tree to handle ISerializable deserialization</returns>
        public static Expression GenerateISerializableExpression(Type type,
                                                                 List <ParameterExpression> variables,
                                                                 ParameterExpression inputStream,
                                                                 ParameterExpression objTracker)
        {
            var newInstance = Expression.Parameter(type, "newInstance");
            var trackType   = Expression.Parameter(typeof(byte), "trackType");

            variables.Add(newInstance);
            variables.Add(trackType);

            var dictionaryType        = DictionaryHelper.GetDictionaryType(type, throwIfNotADictionary: false);
            var notTrackedExpressions = new List <Expression>();

            if (dictionaryType == null)
            {
                notTrackedExpressions.Add(PrimitiveHelpers.ReadByte(inputStream, objTracker));
                notTrackedExpressions.Add(DeserializeISerializable(type, variables, inputStream, objTracker, newInstance));
            }
            else
            {
                notTrackedExpressions.Add(Expression.IfThenElse(Expression.Equal(PrimitiveHelpers.ReadByte(inputStream, objTracker), Expression.Constant(1, typeof(int))),
                                                                DeserializeDictionary(type, variables, inputStream, objTracker, newInstance),
                                                                DeserializeISerializable(type, variables, inputStream, objTracker, newInstance)));
            }

            return(Deserializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                         inputStream,
                                                                         objTracker,
                                                                         newInstance,
                                                                         notTrackedExpressions,
                                                                         trackType,
                                                                         variables));
        }
Example #2
0
        private static IEnumerable <Expression> ReadDimensionalArrayLength(ParameterExpression inputStream,
                                                                           ParameterExpression objTracker,
                                                                           Expression lengths,
                                                                           Expression i,
                                                                           Expression numberOfDimensions)
        {
            var loopExpressions = new List <Expression>();
            var expressions     = new List <Expression>();

            expressions.Add(Expression.Assign(i, Expression.Constant(0)));
            expressions.Add(Expression.Assign(numberOfDimensions, Expression.Convert(PrimitiveHelpers.ReadByte(inputStream, objTracker), typeof(int))));
            expressions.Add(Expression.Assign(lengths, Expression.Call(CreateArrayMethodInfo.GetCreateArrayMethodInfo(typeof(int)), numberOfDimensions)));

            loopExpressions.Add(Expression.Assign(Expression.ArrayAccess(lengths, i), PrimitiveHelpers.ReadInt32(inputStream, objTracker)));
            loopExpressions.Add(Expression.Assign(i, Expression.Add(i, Expression.Constant(1))));

            var loopBody   = Expression.Block(loopExpressions);
            var breakLabel = Expression.Label("breakLabel");
            var cond       = Expression.LessThan(i, numberOfDimensions);
            var loop       = Expression.Loop(Expression.IfThenElse(cond,
                                                                   loopBody,
                                                                   Expression.Break(breakLabel)),
                                             breakLabel);

            expressions.Add(loop);

            return(expressions);
        }
Example #3
0
        /// <summary>
        /// Generate an expression tree to deserialize a class
        /// </summary>
        /// <param name="inputStream">Stream to read from</param>
        /// <param name="objTracker">Reference tracker</param>
        /// <param name="leftSide">Left side of the assignment</param>
        /// <param name="typeExpr">Type of the class as an expression</param>
        /// <param name="typeName">Type of the class as a string</param>
        /// <param name="typeHashCode">Hashcode of the class</param>
        /// <param name="deserializer">Temporary deserializer variable</param>
        /// <param name="itemType">Type of the class</param>
        /// <returns>An expression tree to deserialize a class</returns>
        internal static Expression GetReadClassExpression(ParameterExpression inputStream,
                                                          ParameterExpression objTracker,
                                                          Expression leftSide,
                                                          ParameterExpression typeExpr,
                                                          ParameterExpression typeName,
                                                          ParameterExpression typeHashCode,
                                                          ParameterExpression deserializer,
                                                          Type itemType)
        {
            var readType = Expression.IfThenElse(Expression.Equal(Expression.Convert(PrimitiveHelpers.ReadByte(inputStream, objTracker), typeof(byte)), Expression.Constant(SerializerObjectTracker.Value0)),
                                                 Expression.Assign(typeExpr, Expression.Call(SerializedTypeResolverMih.GetTypeFromFullName_Type(), Expression.Constant(itemType))),
                                                 Expression.Block(Expression.Assign(typeName, Deserializer.GenerateStringExpression(inputStream, objTracker)),
                                                                  Expression.Assign(typeHashCode, PrimitiveHelpers.ReadInt32(inputStream, objTracker)),
                                                                  Expression.Assign(typeExpr, Expression.Call(SerializedTypeResolverMih.GetTypeFromFullName_String(), typeName)),
                                                                  Expression.IfThen(Expression.NotEqual(typeHashCode, Expression.Property(typeExpr, "HashCode")),
                                                                                    Expression.Throw(Expression.New(TypeWasModifiedSinceSerializationException.GetConstructor(), typeExpr)))));

            var        invokeDeserializer = Expression.Invoke(deserializer, inputStream, objTracker);
            Expression convertExpression  = Expression.Convert(Expression.Call(SerializerMih.ConvertObjectToExpectedType(), invokeDeserializer, Expression.Constant(itemType)), itemType);

            return(Expression.IfThenElse(Expression.Equal(Expression.Convert(PrimitiveHelpers.ReadByte(inputStream, objTracker), typeof(byte)), Expression.Constant(SerializerObjectTracker.Value0)),
                                         Expression.Assign(leftSide, Expression.Constant(null, itemType)),
                                         Expression.Block(
                                             readType,
                                             Expression.Assign(deserializer, Expression.Call(DeserializerMih.GetTypeToObjectDeserializer(), Expression.Property(typeExpr, "Type"))),
                                             Expression.Assign(leftSide, convertExpression))));
        }
Example #4
0
        /// <summary>
        /// Generate an expression to handle the 'is the object null' case
        /// </summary>
        /// <param name="type">Type of the object</param>
        /// <param name="inputStream">Stream to read from</param>
        /// <param name="objTracker">Reference tracker</param>
        /// <param name="newInstance">New deserialized object</param>
        /// <param name="notTrackedExpressions">Expressions to execute if the object is not tracked</param>
        /// <param name="trackType">Type of the tracked object</param>
        /// <param name="variables">Global variables for the expression tree</param>
        /// <returns>An expression tree to handle the 'is the object null' case</returns>
        internal static Expression GenerateNullTrackedOrUntrackedExpression(Type type,
                                                                            ParameterExpression inputStream,
                                                                            ParameterExpression objTracker,
                                                                            ParameterExpression newInstance,
                                                                            List <Expression> notTrackedExpressions,
                                                                            ParameterExpression trackType,
                                                                            List <ParameterExpression> variables)
        {
            var alreadyTrackedExpr = Expression.Assign(newInstance, Expression.Convert(Expression.Call(objTracker, DeserializerObjectTrackerMih.GetTrackedObject(), PrimitiveHelpers.ReadInt32(inputStream, objTracker)), type));

            var notAlreadyTrackedExpr = Expression.Block(notTrackedExpressions);
            var isNotNullExpr         = Expression.Block(Expression.Assign(trackType, Expression.Convert(PrimitiveHelpers.ReadByte(inputStream, objTracker), typeof(byte))),
                                                         Expression.IfThenElse(Expression.Equal(trackType, Expression.Constant(SerializerObjectTracker.Value0)),
                                                                               alreadyTrackedExpr,
                                                                               notAlreadyTrackedExpr));

            var expr = Expression.IfThenElse(Expression.Equal(Expression.Convert(PrimitiveHelpers.ReadByte(inputStream, objTracker), typeof(byte)), Expression.Constant(SerializerObjectTracker.Value0)),
                                             Expression.Assign(newInstance, Expression.Convert(Expression.Constant(null), type)),
                                             isNotNullExpr);

            return(Expression.Block(variables, expr, newInstance));
        }
Example #5
0
        public static Expression GenerateDictionaryGenericExpression(Type type,
                                                                     List <ParameterExpression> variables,
                                                                     ParameterExpression inputStream,
                                                                     ParameterExpression objTracker)
        {
            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 newInstance           = Expression.Parameter(type, "newInstanceDict");
            var comparerType          = Expression.Parameter(typeof(byte), "comparerType");

            var typeExpr     = Expression.Parameter(typeof(TypeWithHashCode), "typeExpr");
            var typeName     = Expression.Parameter(typeof(string), "typeName");
            var typeHashCode = Expression.Parameter(typeof(int), "typeHashCode");
            var deserializer = Expression.Parameter(typeof(Func <Stream, DeserializerObjectTracker, object>), "deserializer");

            variables.Add(deserializer);
            variables.Add(typeExpr);
            variables.Add(typeName);
            variables.Add(typeHashCode);


            variables.Add(newInstance);
            variables.Add(comparerType);

            var genericDictionaryType = DictionaryHelper.GetDictionaryType(type);
            var comparerConstructor   = DictionaryHelper.GetComparerConstructor(type);

            var deserializeDictionaryWithDefaultComparer = DeserializeDictionary(type,
                                                                                 genericDictionaryType,
                                                                                 variables,
                                                                                 newInstance,
                                                                                 inputStream,
                                                                                 objTracker,
                                                                                 deserializer,
                                                                                 typeExpr,
                                                                                 typeName,
                                                                                 typeHashCode,
                                                                                 (exprs, newIns) => exprs.Add(Expression.Assign(newIns, Expression.New(type.GetConstructor(new Type[0])))));

            if (comparerConstructor == null)
            {
                notTrackedExpressions.Add(PrimitiveHelpers.ReadByte(inputStream, objTracker));
                notTrackedExpressions.Add(deserializeDictionaryWithDefaultComparer);
            }
            else
            {
                notTrackedExpressions.Add(Expression.IfThenElse(Expression.Equal(PrimitiveHelpers.ReadByte(inputStream, objTracker), Expression.Constant(0, typeof(int))),
                                                                deserializeDictionaryWithDefaultComparer,
                                                                DeserializeDictionary(type,
                                                                                      genericDictionaryType,
                                                                                      variables,
                                                                                      newInstance,
                                                                                      inputStream,
                                                                                      objTracker,
                                                                                      deserializer,
                                                                                      typeExpr,
                                                                                      typeName,
                                                                                      typeHashCode,
                                                                                      (exprs, newIns) =>
                {
                    var eqType   = typeof(IEqualityComparer <>).MakeGenericType(genericDictionaryType.GetGenericArguments()[0]);
                    var comparer = Expression.Parameter(eqType, "comparer");
                    variables.Add(comparer);
                    exprs.Add(Deserializer.GetReadClassExpression(inputStream,
                                                                  objTracker,
                                                                  comparer,
                                                                  typeExpr,
                                                                  typeName,
                                                                  typeHashCode,
                                                                  deserializer,
                                                                  eqType));
                    exprs.Add(Expression.Assign(newIns, Expression.New(comparerConstructor, comparer)));
                })));
            }



            return(Deserializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                         inputStream,
                                                                         objTracker,
                                                                         newInstance,
                                                                         notTrackedExpressions,
                                                                         comparerType,
                                                                         variables));
        }