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));
        }
Example #2
0
        private static System.Delegate CreateTypeSerializer(Type type)
        {
            InternalSerializationStuff.ValidateSupportedTypes(type);

            var variables      = new List <ParameterExpression>();
            var expressions    = new List <Expression>();
            var outputStream   = Expression.Parameter(typeof(Stream), "outputStream");
            var objToSerialize = Expression.Parameter(type, "objToSerialize");
            var objTracking    = Expression.Parameter(typeof(SerializerObjectTracker), "objTracking");

            var primitiveWriter = GetPrimitiveWriter(type);

            if (primitiveWriter != null)
            {
                Debug.Assert(type.IsPrimitive || type.IsValueType, "Value is not a primitive");
                expressions.Add(primitiveWriter(outputStream, objToSerialize, objTracking));
            }
            else if (type == typeof(string))
            {
                expressions.Add(GenerateStringExpression(outputStream, objToSerialize, objTracking));
            }
            else if (InternalSerializationStuff.ImplementsISerializableWithSerializationConstructor(type))
            {
                expressions.Add(ISerializableSerializer.GenerateISerializableExpression(type, variables, outputStream, objToSerialize, objTracking));
            }
            else if (InternalSerializationStuff.ImplementsDictionaryGeneric(type))
            {
                expressions.Add(DictionarySerializer.GenerateDictionaryGenericExpression(type, variables, outputStream, objToSerialize, objTracking));
            }
            else if (type == typeof(ExpandoObject))
            {
                expressions.Add(ExpandoSerializer.GenerateExpandoObjectExpression(type, variables, outputStream, objToSerialize, objTracking));
            }
            else if (type.IsArray)
            {
                expressions.Add(GenerateArrayExpression(type, outputStream, objToSerialize, objTracking));
            }
            else
            {
                expressions.Add(GenerateClassExpression(type, outputStream, objToSerialize, objTracking));
            }

            var block = Expression.Block(variables, expressions);

            var a = typeof(Action <, ,>).MakeGenericType(typeof(Stream), type, typeof(SerializerObjectTracker));

            return(Expression.Lambda(a, block, outputStream, objToSerialize, objTracking).Compile());
        }