Beispiel #1
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))));
        }
Beispiel #2
0
        /// <summary>
        /// Generate an expression that call the clone implementation method
        /// </summary>
        /// <param name="source">Source object</param>
        /// <param name="refTrackerParam">Reference tracker</param>
        /// <param name="expectedType">Expected type....mostly used for IQueryable detection</param>
        /// <returns>An expression that call the clone implementation method</returns>
        internal static Expression CallCopyExpression(Expression source, ParameterExpression refTrackerParam, Expression expectedType)
        {
            var itemAsObject = Expression.Parameter(typeof(object), "itemAsObject");
            var variables    = new List <ParameterExpression>();

            variables.Add(itemAsObject);

            var expressions = new List <Expression>();

            expressions.Add(Expression.Assign(itemAsObject, Expression.Call(SerializerMih.PrepareObjectForSerialization(), source)));
            expressions.Add(Expression.Assign(itemAsObject, Expression.Call(Expression.Call(ObjectClonerMih.CloneImpl(),
                                                                                            Expression.Call(itemAsObject, ObjectMih.GetTypeMethod())),
                                                                            FuncMih.CloneMethodInvoke(),
                                                                            Expression.Convert(itemAsObject, typeof(object)),
                                                                            refTrackerParam)));
            expressions.Add(Expression.Call(SerializerMih.ConvertObjectToExpectedType(),
                                            itemAsObject,
                                            expectedType));

            return(Expression.Block(variables, expressions));
        }
Beispiel #3
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))));
        }
Beispiel #4
0
        internal static void GenerateCopyFieldsExpressions(IEnumerable <FieldInfo> fields,
                                                           ParameterExpression source,
                                                           ParameterExpression clone,
                                                           List <Expression> expressions,
                                                           ParameterExpression refTrackerParam,
                                                           ParameterExpression clonedItem)
        {
            foreach (var field in fields)
            {
                var cloneField  = Expression.Field(clone, field);
                var sourceField = Expression.Field(source, field);
                if (field.FieldType.IsPrimitive || field.FieldType.IsValueType || (field.FieldType == typeof(string)))
                {
                    if (field.IsInitOnly)
                    {
                        expressions.Add(Expression.Call(CopyReadOnlyFieldMethodInfo.GetMethodInfo(),
                                                        Expression.Constant(field),
                                                        Expression.Convert(sourceField, typeof(object)),
                                                        clone));
                    }
                    else
                    {
                        var from = sourceField;
                        var to   = cloneField;
                        expressions.Add(Expression.Assign(to, from));
                    }
                }
                else
                {
                    var es = new List <Expression>();
                    es.Add(Expression.Assign(clonedItem, Expression.Call(SerializerMih.PrepareObjectForSerialization(), sourceField)));
                    es.Add(Expression.Assign(clonedItem, CallCopyExpression(clonedItem, refTrackerParam, Expression.Constant(field.FieldType))));

                    if (IQueryableCloner.IsGenericIQueryableType(field.FieldType))
                    {
                        Type queryableInterface  = IQueryableCloner.GetInterfaceType(field.FieldType, typeof(IQueryable <>));
                        var  genericArgumentType = queryableInterface.GetGenericArguments()[0];

                        var copy2 = Expression.Convert(clonedItem, field.FieldType);
                        var m     = Expression.Call(typeof(Queryable), "AsQueryable", new Type[] { genericArgumentType }, Expression.Convert(copy2, typeof(IEnumerable <>).MakeGenericType(genericArgumentType)));
                        es.Add(Expression.Assign(clonedItem, m));
                    }

                    if (field.FieldType == typeof(IQueryable))
                    {
                        es.Add(Expression.Assign(clonedItem, Expression.Call(IQueryableMih.ConvertToNonGenericQueryable(), clonedItem)));
                    }

                    if (field.IsInitOnly)
                    {
                        Func <Expression, Expression> assignExpr = exx => Expression.Call(CopyReadOnlyFieldMethodInfo.GetMethodInfo(),
                                                                                          Expression.Constant(field),
                                                                                          Expression.Convert(exx, typeof(object)),
                                                                                          clone);

                        var assignNullExpr = Expression.Call(CopyReadOnlyFieldMethodInfo.GetMethodInfo(),
                                                             Expression.Constant(field),
                                                             Expression.Constant(null, typeof(object)),
                                                             clone);

                        es.Add(clonedItem);
                        var conditionalExpression = Expression.IfThenElse(Expression.NotEqual(sourceField, Expression.Constant(null)),
                                                                          assignExpr(Expression.Block(es)),
                                                                          assignNullExpr);

                        expressions.Add(ObjectCloner.GenerateNullTrackedOrUntrackedExpression(sourceField,
                                                                                              cloneField,
                                                                                              field.FieldType,
                                                                                              refTrackerParam,
                                                                                              conditionalExpression,
                                                                                              trackedExpression: assignExpr)); // todo refactor this horrible method
                    }
                    else
                    {
                        es.Add(Expression.Assign(cloneField, Expression.Convert(clonedItem, field.FieldType)));


                        var conditionalExpression = Expression.IfThenElse(Expression.Equal(sourceField, Expression.Constant(null)),
                                                                          Expression.Assign(cloneField, Expression.Constant(null, field.FieldType)),
                                                                          Expression.Block(es));

                        expressions.Add(ObjectCloner.GenerateNullTrackedOrUntrackedExpression(sourceField,
                                                                                              cloneField,
                                                                                              field.FieldType,
                                                                                              refTrackerParam,
                                                                                              conditionalExpression));
                    }
                }
            }
        }