Exemplo n.º 1
0
        /// <summary>
        /// Generates an expression tree to handle class type serialization
        /// </summary>
        /// <param name="outputStream">Stream to write to</param>
        /// <param name="objTracking">Reference tracker</param>
        /// <param name="item">Source object</param>
        /// <param name="itemAsObj">Source object as an object</param>
        /// <param name="typeExpr">Type of the object as an expression</param>
        /// <param name="serializer">Serializer temporary variable</param>
        /// <param name="itemType">Type of the element</param>
        /// <returns>An expression tree to handle class type serialization</returns>
        internal static Expression GetWriteClassTypeExpression(ParameterExpression outputStream,
                                                               ParameterExpression objTracking,
                                                               Expression item,
                                                               Expression itemAsObj,
                                                               ParameterExpression typeExpr,
                                                               ParameterExpression serializer,
                                                               Type itemType)
        {
            var writeType = Expression.IfThenElse(Expression.Equal(Expression.Call(item, ObjectMih.GetTypeMethod()), Expression.Constant(itemType)),
                                                  Expression.Block(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value0), objTracking),
                                                                   Expression.Assign(typeExpr, Expression.Constant(itemType)),
                                                                   Expression.Assign(itemAsObj, Expression.Convert(item, typeof(object)))),
                                                  Expression.Block(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value1), objTracking),
                                                                   Expression.Assign(itemAsObj, Expression.Call(SerializerMih.PrepareObjectForSerialization(), item)),
                                                                   Expression.Assign(typeExpr, Expression.Call(itemAsObj, ObjectMih.GetTypeMethod())),
                                                                   GenerateStringExpression(outputStream, Expression.Call(SerializedTypeResolverMih.GetShortNameFromType(), typeExpr), objTracking),
                                                                   PrimitiveHelpers.WriteInt32(outputStream, Expression.Call(SerializedTypeResolverMih.GetHashCodeFromType(), typeExpr), objTracking)));

            return(Expression.IfThenElse(Expression.Equal(item, Expression.Constant(null)),
                                         PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value0), objTracking),
                                         Expression.Block(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value1), objTracking),
                                                          writeType,
                                                          Expression.Assign(serializer, Expression.Call(SerializerMih.GetTypeToObjectSerializer(), typeExpr)),
                                                          Expression.Invoke(serializer, outputStream, itemAsObj, objTracking))));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Generates an expression to handle the 'is that object null' case
        /// </summary>
        /// <param name="type">Type of <paramref name="objToSerialize"/></param>
        /// <param name="outputStream">Stream to write to</param>
        /// <param name="objToSerialize">Object to serialize</param>
        /// <param name="objTracking">Reference tracker</param>
        /// <param name="notTrackedExpressions">Expressions that must be executed if the object is not tracked</param>
        /// <param name="variables">Global variables for the expression tree</param>
        /// <returns>An expression to handle the 'is that object null' case</returns>
        internal static Expression GenerateNullTrackedOrUntrackedExpression(Type type,
                                                                            ParameterExpression outputStream,
                                                                            Expression objToSerialize,
                                                                            ParameterExpression objTracking,
                                                                            List <Expression> notTrackedExpressions,
                                                                            List <ParameterExpression> variables)
        {
            var trackedObjectPosition = Expression.Parameter(typeof(int?), "trackedObjectPosition");
            var canBeTracked          = Expression.Parameter(typeof(bool), "canBeTracked");

            variables.Add(trackedObjectPosition);
            variables.Add(canBeTracked);

            var alreadyTrackedExpr = Expression.Block(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value0), objTracking),
                                                      PrimitiveHelpers.WriteInt32(outputStream, Expression.Convert(trackedObjectPosition, typeof(int)), objTracking));

            var isNullExpr = PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value0, typeof(byte)), objTracking);

            var isNotNullExpr = Expression.Block(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value1), objTracking),
                                                 Expression.IfThenElse(Expression.IsTrue(canBeTracked),
                                                                       Expression.Assign(trackedObjectPosition, Expression.Call(objTracking, SerializerObjectTrackerMih.GetTrackedObjectIndex(), Expression.Convert(objToSerialize, typeof(object)))),
                                                                       Expression.Assign(trackedObjectPosition, Expression.Convert(Expression.Constant(null), typeof(int?)))),
                                                 Expression.IfThenElse(Expression.NotEqual(trackedObjectPosition, Expression.Constant(null, typeof(int?))),
                                                                       alreadyTrackedExpr,
                                                                       Expression.Block(new[] { PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value1), objTracking) }.Concat(notTrackedExpressions))));

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

            expressions.Add(Expression.Assign(canBeTracked, Expression.Call(objTracking, SerializerObjectTrackerMih.CanBeTracked(), Expression.Constant(type))));
            expressions.Add(Expression.IfThenElse(Expression.AndAlso(Expression.IsTrue(canBeTracked), Expression.Equal(Expression.Convert(objToSerialize, typeof(object)), Expression.Constant(null))),
                                                  isNullExpr,
                                                  isNotNullExpr));

            return(Expression.Block(variables, expressions));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Generates an expression tree to handle ExpandoObject serialization
        /// </summary>
        /// <param name="type">Type of <paramref name="objToSerialize"/></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 ExpandoObject serialization</returns>
        public static Expression GenerateExpandoObjectExpression(Type type,
                                                                 List <ParameterExpression> variables,
                                                                 ParameterExpression outputStream,
                                                                 ParameterExpression objToSerialize,
                                                                 ParameterExpression objTracking)
        {
            var enumerableType          = typeof(IEnumerable <KeyValuePair <string, object> >);
            var getEnumeratorMethodInfo = IEnumerableMih.GetEnumerator <string, object>();
            var enumeratorMethod        = Expression.Call(Expression.Convert(objToSerialize, enumerableType), getEnumeratorMethodInfo);

            var loopBodyCargo = new EnumerableLoopBodyCargo();

            loopBodyCargo.EnumeratorType = typeof(IEnumerator <KeyValuePair <string, object> >);
            loopBodyCargo.KvpType        = typeof(KeyValuePair <string, object>);

            var preLoopActions = new List <Expression>();

            preLoopActions.Add(PrimitiveHelpers.WriteInt32(outputStream, Expression.Property(Expression.Convert(objToSerialize, typeof(ICollection <KeyValuePair <string, object> >)), CollectionMih.Count <KeyValuePair <string, object> >()), objTracking));

            var notTrackedExpressions = new List <Expression>();

            notTrackedExpressions.Add(Expression.Call(objTracking, SerializerObjectTrackerMih.TrackObject(), objToSerialize));
            notTrackedExpressions.Add(EnumerableLoopHelper.GenerateEnumeratorLoop(variables,
                                                                                  EnumerableLoopHelper.GetStringToSomethingWriter(outputStream, objTracking),
                                                                                  enumeratorMethod,
                                                                                  preLoopActions,
                                                                                  loopBodyCargo));

            return(Serializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                       outputStream,
                                                                       objToSerialize,
                                                                       objTracking,
                                                                       notTrackedExpressions,
                                                                       variables));
        }
Exemplo n.º 4
0
        internal static Expression SerializeDictionary(Type type,
                                                       Type dictionaryType,
                                                       List <ParameterExpression> variables,
                                                       ParameterExpression outputStream,
                                                       ParameterExpression objToSerialize,
                                                       ParameterExpression objTracking,
                                                       bool addTracking)
        {
            MethodInfo getEnumeratorMethodInfo = type.GetMethod("GetEnumerator");
            var        enumeratorMethod        = Expression.Call(Expression.Convert(objToSerialize, type), getEnumeratorMethodInfo);

            var loopBodyCargo = new EnumerableLoopBodyCargo();

            loopBodyCargo.EnumeratorType = getEnumeratorMethodInfo.ReturnType;
            loopBodyCargo.KvpType        = typeof(KeyValuePair <,>).MakeGenericType(dictionaryType.GetGenericArguments());

            var notTrackedExpressions = new List <Expression>();

            if (addTracking)
            {
                notTrackedExpressions.Add(Expression.Call(objTracking, SerializerObjectTrackerMih.TrackObject(), objToSerialize));
                notTrackedExpressions.Add(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value1), objTracking));
            }

            notTrackedExpressions.Add(PrimitiveHelpers.WriteInt32(outputStream, Expression.Property(Expression.Convert(objToSerialize, dictionaryType), "Count"), objTracking));

            notTrackedExpressions.Add(EnumerableLoopHelper.GenerateEnumeratorLoop(variables,
                                                                                  GetKeyValuePairLoopBodyCargo(outputStream, objTracking, "Key", dictionaryType.GetGenericArguments()[0], "Value", dictionaryType.GetGenericArguments()[1]),
                                                                                  enumeratorMethod,
                                                                                  null,
                                                                                  loopBodyCargo));

            return(Expression.Block(notTrackedExpressions));
        }
Exemplo n.º 5
0
        private static IEnumerable <Expression> WriteDimensionalArrayLength(ParameterExpression outputStream,
                                                                            Expression objTracking,
                                                                            Expression i,
                                                                            ParameterExpression arr,
                                                                            ParameterExpression lengths,
                                                                            int rank)
        {
            var expressions = new List <Expression>();

            expressions.Add(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant((byte)rank), objTracking));

            var loopExpressions = new List <Expression>();

            expressions.Add(Expression.Assign(i, Expression.Constant(0)));

            var length = Expression.Call(arr, ArrayMih.GetLength(), i);

            loopExpressions.Add(Expression.Assign(Expression.ArrayAccess(lengths, i), length));
            loopExpressions.Add(PrimitiveHelpers.WriteInt32(outputStream, Expression.ArrayIndex(lengths, i), objTracking));
            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, Expression.Constant(rank));
            var loop       = Expression.Loop(Expression.IfThenElse(cond,
                                                                   loopBody,
                                                                   Expression.Break(breakLabel)),
                                             breakLabel);

            expressions.Add(loop);

            return(expressions);
        }
        private static Expression SerializeISerializable(Type type,
                                                         List <ParameterExpression> variables,
                                                         ParameterExpression outputStream,
                                                         ParameterExpression objToSerialize,
                                                         ParameterExpression objTracking)
        {
            var fc      = Expression.Parameter(typeof(FormatterConverter), "fc");
            var context = Expression.Parameter(typeof(StreamingContext), "context");
            var si      = Expression.Parameter(typeof(SerializationInfo), "si");
            var iser    = Expression.Parameter(typeof(ISerializable), "iser");

            variables.Add(fc);
            variables.Add(context);
            variables.Add(si);
            variables.Add(iser);

            var getEnumeratorMethodInfo = SerializationInfoMih.GetEnumerator();

            var enumeratorMethod = Expression.Call(si, getEnumeratorMethodInfo);

            var loopBodyCargo = new EnumerableLoopBodyCargo();

            loopBodyCargo.EnumeratorType = typeof(SerializationInfoEnumerator);
            loopBodyCargo.KvpType        = typeof(SerializationEntry);

            var preLoopActions = new List <Expression>();

            preLoopActions.Add(PrimitiveHelpers.WriteInt32(outputStream, Expression.Property(si, SerializationInfoMih.MemberCount()), objTracking));

            var notTrackedExpressions = new List <Expression>();

            notTrackedExpressions.Add(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value0, typeof(byte)), objTracking));
            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(iser, Expression.Convert(objToSerialize, typeof(ISerializable))));
            notTrackedExpressions.AddRange(SerializationCallbacksHelper.GenerateOnSerializingAttributeExpression(type, objToSerialize, context));
            notTrackedExpressions.Add(Expression.Call(iser, ISerializableMih.GetObjectData(), si, context));
            notTrackedExpressions.AddRange(SerializationCallbacksHelper.GenerateOnSerializedAttributeExpression(type, objToSerialize, context));
            notTrackedExpressions.Add(Expression.IfThen(Expression.IsTrue(Expression.Property(si, "IsFullTypeNameSetExplicit")),
                                                        Expression.Throw(Expression.New(InvalidOperationExceptionMih.Constructor(), Expression.Constant("Changing the full type name for an ISerializable is not supported")))));
            notTrackedExpressions.Add(Expression.IfThen(Expression.IsTrue(Expression.Property(si, "IsAssemblyNameSetExplicit")),
                                                        Expression.Throw(Expression.New(InvalidOperationExceptionMih.Constructor(), Expression.Constant("Changing the assembly name for an ISerializable is not supported")))));
            notTrackedExpressions.Add(EnumerableLoopHelper.GenerateEnumeratorLoop(variables,
                                                                                  DictionarySerializer.GetKeyValuePairLoopBodyCargo(outputStream, objTracking, "Name", typeof(string), "Value", typeof(object)),
                                                                                  enumeratorMethod,
                                                                                  preLoopActions,
                                                                                  loopBodyCargo));
            notTrackedExpressions.Add(Expression.Call(objTracking, SerializerObjectTrackerMih.TrackObject(), objToSerialize));

            return(Expression.Block(notTrackedExpressions));
        }
Exemplo n.º 7
0
        private static IEnumerable <Expression> WriteJaggedArray(Type elementType,
                                                                 List <ParameterExpression> variables,
                                                                 ParameterExpression outputStream,
                                                                 ParameterExpression arr,
                                                                 ParameterExpression objTracking)
        {
            var item       = Expression.Parameter(elementType, "item");
            var serializer = Expression.Parameter(typeof(Action <Stream, object, SerializerObjectTracker>), "serializer");
            var itemAsObj  = Expression.Parameter(typeof(object), "itemAsObj");
            var typeExpr   = Expression.Parameter(typeof(Type), "typeExpr");
            var i          = Expression.Parameter(typeof(int), "i");
            var length     = Expression.Parameter(typeof(int), "length");

            variables.Add(typeExpr);
            variables.Add(itemAsObj);
            variables.Add(serializer);
            variables.Add(item);
            variables.Add(length);
            variables.Add(i);

            var expressions = new List <Expression>();

            expressions.Add(Expression.Assign(length, Expression.Property(arr, "Length")));
            expressions.Add(PrimitiveHelpers.WriteInt32(outputStream, length, objTracking));
            expressions.Add(Expression.Assign(i, Expression.Constant(0)));

            Debug.Assert(!elementType.IsPrimitive && !elementType.IsValueType && elementType != typeof(string), "Type cannot be a primitive");

            var loopExpressions = new List <Expression>();

            loopExpressions.Add(Expression.Assign(item, Expression.ArrayAccess(arr, i)));   // uh?
            loopExpressions.Add(Expression.Assign(item, Expression.Convert(Expression.Call(arr, ArrayMih.GetValue(), i), elementType)));
            loopExpressions.Add(Serializer.GetWriteClassTypeExpression(outputStream, objTracking, item, itemAsObj, typeExpr, serializer, elementType));
            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);
        }