Exemplo n.º 1
0
        /// <summary>
        /// Generates an expression tree to read a string
        /// </summary>
        /// <param name="inputStream">Stream to read from</param>
        /// <param name="objTracking">Reference tracker</param>
        /// <returns>An expression tree to read a string</returns>
        internal static Expression GenerateStringExpression(ParameterExpression inputStream,
                                                            ParameterExpression objTracking)
        {
            List <ParameterExpression> variables = new List <ParameterExpression>();

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

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

            List <Expression> notTrackedExpressions = new List <Expression>();

            notTrackedExpressions.Add(Expression.Assign(newInstance, PrimitiveHelpers.ReadString(inputStream, objTracking)));
            notTrackedExpressions.Add(Expression.Call(objTracking, DeserializerObjectTrackerMih.TrackedObject(), newInstance));

            return(Deserializer.GenerateNullTrackedOrUntrackedExpression(typeof(string),
                                                                         inputStream,
                                                                         objTracking,
                                                                         newInstance,
                                                                         notTrackedExpressions,
                                                                         trackType,
                                                                         variables));
        }
Exemplo n.º 2
0
        private static Expression GenerateClassExpression(Type type,
                                                          ParameterExpression inputStream,
                                                          ParameterExpression objTracker)
        {
            List <ParameterExpression> variables = new List <ParameterExpression>();

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

            variables.Add(trackType);
            variables.Add(newInstance);
            variables.Add(deserializer);
            variables.Add(typeExpr);
            variables.Add(typeName);
            variables.Add(typeHashCode);
            var temporaryVariables = new Dictionary <Type, ParameterExpression>();

            List <Expression> notTrackedExpressions = new List <Expression>();

            notTrackedExpressions.Add(Expression.Assign(newInstance, Expression.Convert(Expression.Call(FormatterServicesMih.GetUninitializedObject(), Expression.Constant(type)), type)));
            notTrackedExpressions.AddRange(SerializationCallbacksHelper.GenerateOnDeserializingAttributeExpression(type, newInstance, Expression.New(StreamingContextMih.Constructor(), Expression.Constant(StreamingContextStates.All))));

            if (type.IsClass)
            {
                notTrackedExpressions.Add(Expression.Call(objTracker, DeserializerObjectTrackerMih.TrackedObject(), newInstance));
            }

            GenerateReadFieldsExpression(type,
                                         InternalSerializationStuff.GetFields(type),
                                         inputStream,
                                         objTracker,
                                         temporaryVariables,
                                         variables,
                                         newInstance,
                                         notTrackedExpressions,
                                         typeExpr,
                                         typeName,
                                         typeHashCode,
                                         deserializer);

            notTrackedExpressions.AddRange(SerializationCallbacksHelper.GenerateOnDeserializedAttributeExpression(type, newInstance, Expression.New(StreamingContextMih.Constructor(), Expression.Constant(StreamingContextStates.All))));
            notTrackedExpressions.Add(SerializationCallbacksHelper.GenerateCallIDeserializationExpression(type, newInstance));

            return(Deserializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                         inputStream,
                                                                         objTracker,
                                                                         newInstance,
                                                                         notTrackedExpressions,
                                                                         trackType,
                                                                         variables));
        }
        private static IEnumerable <Expression> ReadJaggedArray(Type type,
                                                                Type elementType,
                                                                ParameterExpression newInstance,
                                                                List <ParameterExpression> variables,
                                                                ParameterExpression inputStream,
                                                                ParameterExpression objTracker)
        {
            var i            = Expression.Parameter(typeof(int), "i");
            var length       = Expression.Parameter(typeof(int), "length");
            var item         = Expression.Parameter(type.GetElementType(), "item");
            var typeName     = Expression.Parameter(typeof(string), "typeName");
            var typeExpr     = Expression.Parameter(typeof(TypeWithHashCode), "type");
            var typeHashCode = Expression.Parameter(typeof(int), "typeHashCode");
            var tmpValue     = Expression.Parameter(elementType, "tmpValue");
            var deserializer = Expression.Parameter(typeof(Func <Stream, DeserializerObjectTracker, object>), "deserializer");

            variables.Add(length);
            variables.Add(item);
            variables.Add(typeName);
            variables.Add(typeExpr);
            variables.Add(typeHashCode);
            variables.Add(i);
            variables.Add(tmpValue);
            variables.Add(deserializer);

            var expressions = new List <Expression>();

            expressions.Add(Expression.Assign(length, PrimitiveHelpers.ReadInt32(inputStream, objTracker)));
            expressions.Add(Expression.Assign(i, Expression.Constant(0)));
            expressions.Add(Expression.Assign(newInstance, Expression.Convert(Expression.New(type.GetConstructor(new[] { typeof(int) }), length), type)));
            if (type.IsClass)
            {
                expressions.Add(Expression.Call(objTracker, DeserializerObjectTrackerMih.TrackedObject(), newInstance));
            }

            var loopExpressions = new List <Expression>();

            loopExpressions.Add(Deserializer.GetReadClassExpression(inputStream, objTracker, tmpValue, typeExpr, typeName, typeHashCode, deserializer, elementType));
            loopExpressions.Add(Expression.Call(newInstance, ArrayMih.SetValue(), Expression.Convert(tmpValue, typeof(object)), i));
            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);

            expressions.Add(loop);
            return(expressions);
        }
Exemplo n.º 4
0
        private static Expression DeserializeDictionary(Type type,
                                                        Type genericDictionaryType,
                                                        List <ParameterExpression> variables,
                                                        ParameterExpression newInstance,
                                                        ParameterExpression inputStream,
                                                        ParameterExpression objTracker,
                                                        ParameterExpression deserializer,
                                                        ParameterExpression typeExpr,
                                                        ParameterExpression typeName,
                                                        ParameterExpression typeHashCode,
                                                        Action <List <Expression>, ParameterExpression> createClassAction)
        {
            var expressions = new List <Expression>();

            var trackType = Expression.Parameter(typeof(byte), "isAlreadyTracked");

            variables.Add(trackType);
            var temporaryVariables = new Dictionary <Type, ParameterExpression>();

            var fields = InternalSerializationStuff.GetFields(type, genericDictionaryType);

            createClassAction(expressions, newInstance);
            expressions.Add(Expression.Call(objTracker, DeserializerObjectTrackerMih.TrackedObject(), newInstance));

            Deserializer.GenerateReadFieldsExpression(type,
                                                      fields,
                                                      inputStream,
                                                      objTracker,
                                                      temporaryVariables,
                                                      variables,
                                                      newInstance,
                                                      expressions,
                                                      typeExpr,
                                                      typeName,
                                                      typeHashCode,
                                                      deserializer);

            expressions.AddRange(DeserializeDictionaryValues(type, variables, inputStream, objTracker, newInstance));

            //expressions.AddRange(SerializationCallbacksHelper.GenerateOnDeserializedAttributeExpression(type, newInstance, Expression.New(StreamingContextMih.Constructor(), Expression.Constant(StreamingContextStates.All))));
            //expressions.Add(SerializationCallbacksHelper.GenerateCallIDeserializationExpression(type, newInstance));

            return(Expression.Block(expressions));
        }
Exemplo n.º 5
0
        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));
        }
Exemplo n.º 6
0
        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));
        }
Exemplo n.º 7
0
        /// <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));
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
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));
        }