Esempio n. 1
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));
        }
Esempio n. 2
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));
        }
        /// <summary>
        /// Generates an expression tree to handle jagged array serialization
        /// </summary>
        /// <param name="type">Type of array</param>
        /// <param name="elementType">Type of the elements contained in the array</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 jagged array serialization</returns>
        internal static Expression GenerateJaggedArray(Type type,
                                                       Type elementType,
                                                       ParameterExpression outputStream,
                                                       ParameterExpression objToSerialize,
                                                       ParameterExpression objTracking)
        {
            List <Expression>          notTrackedExpressions = new List <Expression>();
            List <ParameterExpression> variables             = new List <ParameterExpression>();

            var trackedObjectPosition = Expression.Parameter(typeof(int?), "trackedObjectPosition");
            var arr = Expression.Parameter(type, "arr");

            variables.Add(trackedObjectPosition);
            variables.Add(arr);

            notTrackedExpressions.Add(Expression.Call(objTracking, SerializerObjectTrackerMih.TrackObject(), objToSerialize));
            notTrackedExpressions.Add(Expression.Assign(arr, Expression.Convert(objToSerialize, type)));
            notTrackedExpressions.AddRange(WriteJaggedArray(elementType, variables, outputStream, arr, objTracking));

            return(Serializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                       outputStream,
                                                                       objToSerialize,
                                                                       objTracking,
                                                                       notTrackedExpressions,
                                                                       variables));
        }
Esempio n. 4
0
        internal static void GenerateFieldsExpression(Type type,
                                                      FieldInfo[] fields,
                                                      ParameterExpression outputStream,
                                                      Expression objToSerialize,
                                                      ParameterExpression objTracking,
                                                      List <ParameterExpression> variables,
                                                      List <Expression> notTrackedExpressions)
        {
            var serializer = Expression.Parameter(typeof(Action <Stream, object, SerializerObjectTracker>), "serializer");
            var typeExpr   = Expression.Parameter(typeof(Type), "typeExpr");
            var itemAsObj  = Expression.Parameter(typeof(object), "itemAsObj");

            variables.Add(serializer);
            variables.Add(typeExpr);
            variables.Add(itemAsObj);

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

            if (type.IsClass)
            {
                copyFieldsExpressions.Add(Expression.Call(objTracking, SerializerObjectTrackerMih.TrackObject(), objToSerialize));
            }

            notTrackedExpressions.AddRange(SerializationCallbacksHelper.GenerateOnSerializingAttributeExpression(type, objToSerialize, Expression.New(StreamingContextMih.Constructor(), Expression.Constant(StreamingContextStates.All))));

            foreach (var fieldInfo in fields)
            {
                var fieldValueExpr = Expression.Field(Expression.Convert(objToSerialize, type), fieldInfo);

                if (fieldInfo.FieldType == typeof(string))
                {
                    copyFieldsExpressions.Add(GenerateStringExpression(outputStream, fieldValueExpr, objTracking));
                }
                else if (fieldInfo.FieldType.IsPrimitive || fieldInfo.FieldType.IsValueType)
                {
                    var primitiveWriter = GetPrimitiveWriter(fieldInfo.FieldType);

                    if (primitiveWriter == null)
                    {
                        var primitiveSerializer = GetTypeSerializer(fieldInfo.FieldType);
                        copyFieldsExpressions.Add(Expression.Invoke(Expression.Constant(primitiveSerializer), outputStream, fieldValueExpr, objTracking));
                    }
                    else
                    {
                        copyFieldsExpressions.Add(primitiveWriter(outputStream, fieldValueExpr, objTracking));
                    }
                }
                else
                {
                    copyFieldsExpressions.Add(GetWriteClassTypeExpression(outputStream, objTracking, fieldValueExpr, itemAsObj, typeExpr, serializer, fieldInfo.FieldType));
                }
            }

            notTrackedExpressions.AddRange(copyFieldsExpressions);
            notTrackedExpressions.AddRange(SerializationCallbacksHelper.GenerateOnSerializedAttributeExpression(type, objToSerialize, Expression.New(StreamingContextMih.Constructor(), Expression.Constant(StreamingContextStates.All))));
        }
        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));
        }
Esempio n. 6
0
        /// <summary>
        /// Generates an expression tree to handle string serialization
        /// </summary>
        /// <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 string serialization</returns>
        internal static Expression GenerateStringExpression(ParameterExpression outputStream,
                                                            Expression objToSerialize,
                                                            ParameterExpression objTracking)
        {
            List <Expression>          notTrackedExpressions = new List <Expression>();
            List <ParameterExpression> variables             = new List <ParameterExpression>();

            notTrackedExpressions.Add(Expression.Call(objTracking, SerializerObjectTrackerMih.TrackObject(), objToSerialize));
            notTrackedExpressions.Add(PrimitiveHelpers.WriteString(outputStream, objToSerialize, objTracking));

            return(GenerateNullTrackedOrUntrackedExpression(typeof(string),
                                                            outputStream,
                                                            objToSerialize,
                                                            objTracking,
                                                            notTrackedExpressions,
                                                            variables));
        }
Esempio n. 7
0
        /// <summary>
        /// Generate an expression tree to handle array serialization
        /// </summary>
        /// <param name="type">Type of the array</param>
        /// <param name="elementType">Type of the elements contained inside the array</param>
        /// <param name="outputStream">Stream that is written to</param>
        /// <param name="objToSerialize">Object to serialize</param>
        /// <param name="objTracking">Reference tracker</param>
        /// <returns>An expression tree to handle array serialization</returns>
        internal static Expression GenerateArrayOfKnownDimension(Type type,
                                                                 Type elementType,
                                                                 ParameterExpression outputStream,
                                                                 ParameterExpression objToSerialize,
                                                                 ParameterExpression objTracking)
        {
            List <Expression>          notTrackedExpressions = new List <Expression>();
            List <ParameterExpression> variables             = new List <ParameterExpression>();

            var i       = Expression.Parameter(typeof(int), "i");
            var lengths = Expression.Parameter(typeof(int[]), "lengths");
            var trackedObjectPosition = Expression.Parameter(typeof(int?), "trackedObjectPosition");
            var arr  = Expression.Parameter(type, "arr");
            var rank = type.GetArrayRank();

            variables.Add(trackedObjectPosition);
            variables.Add(i);
            variables.Add(lengths);
            variables.Add(arr);

            notTrackedExpressions.Add(Expression.Call(objTracking, SerializerObjectTrackerMih.TrackObject(), objToSerialize));
            notTrackedExpressions.Add(Expression.Assign(arr, Expression.Convert(objToSerialize, type)));
            notTrackedExpressions.Add(Expression.Assign(lengths, Expression.Call(CreateArrayMethodInfo.GetCreateArrayMethodInfo(typeof(int)), Expression.Constant(rank))));
            notTrackedExpressions.Add(Expression.Assign(i, Expression.Constant(0)));
            notTrackedExpressions.Add(Expression.IfThen(Expression.GreaterThanOrEqual(Expression.Constant(rank), Expression.Constant(255)),
                                                        Expression.Throw(Expression.New(NotSupportedExceptionMih.ConstructorString(), Expression.Constant("Array with more than 255 dimensions are not supported")))));
            notTrackedExpressions.AddRange(WriteDimensionalArrayLength(outputStream, objTracking, i, arr, lengths, rank));
            notTrackedExpressions.AddRange(WriteDimensionalArray(elementType, variables, outputStream, arr, rank, lengths, objTracking));

            return(Serializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                       outputStream,
                                                                       objToSerialize,
                                                                       objTracking,
                                                                       notTrackedExpressions,
                                                                       variables));
        }
Esempio n. 8
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));
        }