示例#1
0
        private static Func <EnumerableLoopBodyCargo, Expression> CloneKeyValuePair(ParameterExpression clone,
                                                                                    ParameterExpression refTrackerParam)
        {
            Func <EnumerableLoopBodyCargo, Expression> loopBody = cargo =>
            {
                var keyExpression   = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetTypeInfo().GetDeclaredProperty("Current")), cargo.KvpType.GetTypeInfo().GetDeclaredProperty("Key"));
                var valueExpression = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetTypeInfo().GetDeclaredProperty("Current")), cargo.KvpType.GetTypeInfo().GetDeclaredProperty("Value"));

                var addExpr = Expression.Call(clone,
                                              DictionaryMih.Add <string, object>(),
                                              keyExpression,
                                              ClassCloner.CallCopyExpression(valueExpression,
                                                                             refTrackerParam,
                                                                             Expression.Call(valueExpression, ObjectMih.GetTypeMethod())));
                var addNullExpr = Expression.Call(clone,
                                                  DictionaryMih.Add <string, object>(),
                                                  keyExpression,
                                                  Expression.Constant(null));

                return(Expression.IfThenElse(Expression.NotEqual(valueExpression, Expression.Constant(null)),
                                             addExpr,
                                             addNullExpr));
            };

            return(loopBody);
        }
示例#2
0
        internal static List <Expression> DeserializeDictionaryValues(Type type,
                                                                      List <ParameterExpression> variables,
                                                                      ParameterExpression inputStream,
                                                                      ParameterExpression objTracker,
                                                                      ParameterExpression newInstance)
        {
            var dictionaryType = DictionaryHelper.GetDictionaryType(type);
            var keyType        = dictionaryType.GetGenericArguments()[0];
            var valueType      = dictionaryType.GetGenericArguments()[1];

            var i            = Expression.Parameter(typeof(int), "i");
            var length       = Expression.Parameter(typeof(int), "length");
            var key          = Expression.Parameter(keyType, "key");
            var value        = Expression.Parameter(dictionaryType.GetGenericArguments()[1], "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");

            variables.Add(i);
            variables.Add(length);
            variables.Add(key);
            variables.Add(value);
            variables.Add(typeName);
            variables.Add(typeExpr);
            variables.Add(deserializer);
            variables.Add(typeHashCode);

            var loopExpressions = new List <Expression>();

            GetReadExpression(inputStream, objTracker, keyType, loopExpressions, key, typeExpr, typeName, typeHashCode, deserializer);
            GetReadExpression(inputStream, objTracker, valueType, loopExpressions, value, typeExpr, typeName, typeHashCode, deserializer);
            loopExpressions.Add(Expression.Call(newInstance, DictionaryMih.Add(dictionaryType, keyType, dictionaryType.GetGenericArguments()[1]), 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(loop);
            notTrackedExpressions.Add(newInstance);

            return(notTrackedExpressions);
        }
示例#3
0
        public static Expression GenerateDictionaryGenericExpression(List <ParameterExpression> variables,
                                                                     ParameterExpression source,
                                                                     ParameterExpression clone,
                                                                     Type sourceType,
                                                                     ParameterExpression refTrackerParam)
        {
            var ctor = sourceType.GetConstructor(new Type[0]);

            if (ctor == null)
            {
                throw new MissingConstructorException("Type " + sourceType + " must have a public constructor without parameter.");
            }

            var genericDictionaryType = DictionaryHelper.GetDictionaryType(sourceType);
            var comparerConstructor   = DictionaryHelper.GetComparerConstructor(sourceType);
            var cloneDictionaryWithDefaultComparer = CloneDictionaryWithDefaultComparer(genericDictionaryType,
                                                                                        variables,
                                                                                        source,
                                                                                        clone,
                                                                                        sourceType,
                                                                                        refTrackerParam);

            if (comparerConstructor == null)
            {
                return(cloneDictionaryWithDefaultComparer);
            }

            return(Expression.IfThenElse(Expression.IsTrue(Expression.Call(DictionaryMih.IsDefaultEqualityComparer(),
                                                                           Expression.Constant(genericDictionaryType.GetGenericArguments()[0]),
                                                                           Expression.Property(source, nameof(Dictionary <int, int> .Comparer)))),
                                         cloneDictionaryWithDefaultComparer,
                                         CloneDictionaryWithCustomComparer(genericDictionaryType,
                                                                           comparerConstructor,
                                                                           variables,
                                                                           source,
                                                                           clone,
                                                                           sourceType,
                                                                           refTrackerParam)));
        }
        /// <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));
        }
        /// <summary>
        /// Generates an expression tree to handle ISerializable serialization
        /// </summary>
        /// <param name="type">Type of the object to serialize</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 ISerializable serialization</returns>
        public static Expression GenerateISerializableExpression(Type type,
                                                                 List <ParameterExpression> variables,
                                                                 ParameterExpression outputStream,
                                                                 ParameterExpression objToSerialize,
                                                                 ParameterExpression objTracking)
        {
            if (GetSerializationConstructor(type) == null)
            {
                throw new MissingConstructorException("Cannot serialize type " + type + " because it does not have the required constructor for ISerializable.  If you inherits from a class that implements ISerializable you have to expose the serialization constructor.");
            }

            var dictionaryType        = DictionaryHelper.GetDictionaryType(type, throwIfNotADictionary: false);
            var notTrackedExpressions = new List <Expression>();

            if (dictionaryType == null)
            {
                notTrackedExpressions.Add(SerializeISerializable(type, variables, outputStream, objToSerialize, objTracking));
            }
            else
            {
                notTrackedExpressions.Add(Expression.IfThenElse(Expression.IsTrue(Expression.Call(DictionaryMih.IsObjectADictionaryWithDefaultComparerAndNoAdditionalProperties(), objToSerialize)),
                                                                DictionarySerializer.SerializeDictionary(type, dictionaryType, variables, outputStream, objToSerialize, objTracking, true),
                                                                SerializeISerializable(type, variables, outputStream, objToSerialize, objTracking)));
            }

            return(Serializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                       outputStream,
                                                                       objToSerialize,
                                                                       objTracking,
                                                                       notTrackedExpressions,
                                                                       variables));
        }
示例#6
0
        public static Expression GenerateDictionaryGenericExpression(Type type,
                                                                     List <ParameterExpression> variables,
                                                                     ParameterExpression outputStream,
                                                                     ParameterExpression objToSerialize,
                                                                     ParameterExpression objTracking)
        {
            var ctor = type.GetConstructor(new Type[0]);

            if (ctor == null)
            {
                throw new MissingConstructorException("Type " + type + " must have a public constructor without parameter.");
            }

            var notTrackedExpressions = new List <Expression>();

            var genericDictionaryType = DictionaryHelper.GetDictionaryType(type);
            var comparerConstructor   = DictionaryHelper.GetComparerConstructor(type);
            var serializeDictionaryWithDefaultComparer = SerializeDictionaryWithDefaultComparer(genericDictionaryType,
                                                                                                variables,
                                                                                                type,
                                                                                                outputStream,
                                                                                                objToSerialize,
                                                                                                objTracking);

            if (comparerConstructor == null)
            {
                notTrackedExpressions.Add(serializeDictionaryWithDefaultComparer);
            }
            else
            {
                notTrackedExpressions.Add(Expression.IfThenElse(Expression.IsTrue(Expression.Call(DictionaryMih.IsDefaultEqualityComparer(),
                                                                                                  Expression.Constant(genericDictionaryType.GetGenericArguments()[0]),
                                                                                                  Expression.Property(objToSerialize, nameof(Dictionary <int, int> .Comparer)))),
                                                                serializeDictionaryWithDefaultComparer,
                                                                SerializeDictionaryWithCustomComparer(genericDictionaryType,
                                                                                                      variables,
                                                                                                      type,
                                                                                                      outputStream,
                                                                                                      objToSerialize,
                                                                                                      objTracking)));
            }

            return(Serializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                       outputStream,
                                                                       objToSerialize,
                                                                       objTracking,
                                                                       notTrackedExpressions,
                                                                       variables));
        }