/// <summary>
        /// Generates an expression tree to handle jagged array deserialization
        /// </summary>
        /// <param name="type">Type of array</param>
        /// <param name="inputStream">Stream to read from</param>
        /// <param name="objTracking">Reference tracker</param>
        /// <returns>An expression tree to handle jagged array deserialization</returns>
        public static Expression GenerateJaggedArray(Type type,
                                                     ParameterExpression inputStream,
                                                     ParameterExpression objTracking)
        {
            List <ParameterExpression> variables = new List <ParameterExpression>();

            var elementType        = type.GetElementType();
            var trackType          = Expression.Parameter(typeof(byte), "trackType");
            var newInstance        = Expression.Parameter(type, "newInstance");
            var numberOfDimensions = Expression.Parameter(typeof(int), "numberOfDimensions");
            var lengths            = Expression.Parameter(typeof(int[]), "lengths");
            var item = Expression.Parameter(type.GetElementType(), "item");

            variables.Add(trackType);
            variables.Add(newInstance);
            variables.Add(lengths);
            variables.Add(item);
            variables.Add(numberOfDimensions);

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

            notTrackedExpressions.AddRange(ReadJaggedArray(type, elementType, newInstance, variables, inputStream, objTracking));

            return(Deserializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                         inputStream,
                                                                         objTracking,
                                                                         newInstance,
                                                                         notTrackedExpressions,
                                                                         trackType,
                                                                         variables));
        }
示例#2
0
        /// <summary>
        /// Generates an expression tree to handle ISerializable deserialization
        /// </summary>
        /// <param name="type">Type to deserialize</param>
        /// <param name="variables">Global variables for expression tree</param>
        /// <param name="inputStream">Stream to read from</param>
        /// <param name="objTracker">Reference tracker</param>
        /// <returns>An expression tree to handle ISerializable deserialization</returns>
        public static Expression GenerateISerializableExpression(Type type,
                                                                 List <ParameterExpression> variables,
                                                                 ParameterExpression inputStream,
                                                                 ParameterExpression objTracker)
        {
            var newInstance = Expression.Parameter(type, "newInstance");
            var trackType   = Expression.Parameter(typeof(byte), "trackType");

            variables.Add(newInstance);
            variables.Add(trackType);

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

            if (dictionaryType == null)
            {
                notTrackedExpressions.Add(PrimitiveHelpers.ReadByte(inputStream, objTracker));
                notTrackedExpressions.Add(DeserializeISerializable(type, variables, inputStream, objTracker, newInstance));
            }
            else
            {
                notTrackedExpressions.Add(Expression.IfThenElse(Expression.Equal(PrimitiveHelpers.ReadByte(inputStream, objTracker), Expression.Constant(1, typeof(int))),
                                                                DeserializeDictionary(type, variables, inputStream, objTracker, newInstance),
                                                                DeserializeISerializable(type, variables, inputStream, objTracker, newInstance)));
            }

            return(Deserializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                         inputStream,
                                                                         objTracker,
                                                                         newInstance,
                                                                         notTrackedExpressions,
                                                                         trackType,
                                                                         variables));
        }
示例#3
0
        /// <summary>
        /// Generate an expression tree to handle array deserialization
        /// </summary>
        /// <param name="type">Type of the array</param>
        /// <param name="inputStream">Stream that is read from</param>
        /// <param name="objTracker">Reference tracker</param>
        /// <returns>An expression tree to handle array deserialization</returns>
        internal static Expression GenerateArrayOfKnownDimension(Type type,
                                                                 ParameterExpression inputStream,
                                                                 ParameterExpression objTracker)
        {
            List <ParameterExpression> variables = new List <ParameterExpression>();

            var elementType        = type.GetElementType();
            var trackType          = Expression.Parameter(typeof(byte), "trackType");
            var newInstance        = Expression.Parameter(type, "newInstance");
            var i                  = Expression.Parameter(typeof(int), "i");
            var numberOfDimensions = Expression.Parameter(typeof(int), "numberOfDimensions");
            var lengths            = Expression.Parameter(typeof(int[]), "lengths");
            var item               = Expression.Parameter(type.GetElementType(), "item");

            variables.Add(trackType);
            variables.Add(newInstance);
            variables.Add(i);
            variables.Add(lengths);
            variables.Add(item);
            variables.Add(numberOfDimensions);

            var rank = type.GetArrayRank();
            List <Expression> notTrackedExpressions = new List <Expression>();

            notTrackedExpressions.AddRange(ReadDimensionalArrayLength(inputStream, objTracker, lengths, i, numberOfDimensions));
            notTrackedExpressions.AddRange(ReadDimensionalArray(type, elementType, newInstance, variables, inputStream, lengths, objTracker, rank));

            return(Deserializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                         inputStream,
                                                                         objTracker,
                                                                         newInstance,
                                                                         notTrackedExpressions,
                                                                         trackType,
                                                                         variables));
        }
示例#4
0
        /// <summary>
        /// Generates an expression tree to read a string
        /// </summary>
        /// <param name="inputStream">Stream to read from</param>
        /// <param name="objTracking">Reference tracker</param>
        /// <returns>An expression tree to read a string</returns>
        internal static Expression GenerateStringExpression(ParameterExpression inputStream,
                                                            ParameterExpression objTracking)
        {
            List <ParameterExpression> variables = new List <ParameterExpression>();

            var trackType    = Expression.Parameter(typeof(byte), "isAlreadyTracked");
            var newInstance  = Expression.Parameter(typeof(string), "newInstance");
            var deserializer = Expression.Parameter(typeof(Func <Stream, DeserializerObjectTracker, object>), "deserializer");
            var typeExpr     = Expression.Parameter(typeof(TypeWithHashCode), "typeExpr");
            var typeName     = Expression.Parameter(typeof(string), "typeName");
            var typeHashCode = Expression.Parameter(typeof(int), "typeHashCode");

            variables.Add(trackType);
            variables.Add(newInstance);
            variables.Add(deserializer);
            variables.Add(typeExpr);
            variables.Add(typeName);
            variables.Add(typeHashCode);

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

            notTrackedExpressions.Add(Expression.Assign(newInstance, PrimitiveHelpers.ReadString(inputStream, objTracking)));
            notTrackedExpressions.Add(Expression.Call(objTracking, DeserializerObjectTrackerMih.TrackedObject(), newInstance));

            return(Deserializer.GenerateNullTrackedOrUntrackedExpression(typeof(string),
                                                                         inputStream,
                                                                         objTracking,
                                                                         newInstance,
                                                                         notTrackedExpressions,
                                                                         trackType,
                                                                         variables));
        }
示例#5
0
        private static Expression GenerateClassExpression(Type type,
                                                          ParameterExpression inputStream,
                                                          ParameterExpression objTracker)
        {
            List <ParameterExpression> variables = new List <ParameterExpression>();

            var trackType    = Expression.Parameter(typeof(byte), "isAlreadyTracked");
            var newInstance  = Expression.Parameter(type, "newInstance");
            var deserializer = Expression.Parameter(typeof(Func <Stream, DeserializerObjectTracker, object>), "deserializer");
            var typeExpr     = Expression.Parameter(typeof(TypeWithHashCode), "typeExpr");
            var typeName     = Expression.Parameter(typeof(string), "typeName");
            var typeHashCode = Expression.Parameter(typeof(int), "typeHashCode");

            variables.Add(trackType);
            variables.Add(newInstance);
            variables.Add(deserializer);
            variables.Add(typeExpr);
            variables.Add(typeName);
            variables.Add(typeHashCode);
            var temporaryVariables = new Dictionary <Type, ParameterExpression>();

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

            notTrackedExpressions.Add(Expression.Assign(newInstance, Expression.Convert(Expression.Call(FormatterServicesMih.GetUninitializedObject(), Expression.Constant(type)), type)));
            notTrackedExpressions.AddRange(SerializationCallbacksHelper.GenerateOnDeserializingAttributeExpression(type, newInstance, Expression.New(StreamingContextMih.Constructor(), Expression.Constant(StreamingContextStates.All))));

            if (type.IsClass)
            {
                notTrackedExpressions.Add(Expression.Call(objTracker, DeserializerObjectTrackerMih.TrackedObject(), newInstance));
            }

            GenerateReadFieldsExpression(type,
                                         InternalSerializationStuff.GetFields(type),
                                         inputStream,
                                         objTracker,
                                         temporaryVariables,
                                         variables,
                                         newInstance,
                                         notTrackedExpressions,
                                         typeExpr,
                                         typeName,
                                         typeHashCode,
                                         deserializer);

            notTrackedExpressions.AddRange(SerializationCallbacksHelper.GenerateOnDeserializedAttributeExpression(type, newInstance, Expression.New(StreamingContextMih.Constructor(), Expression.Constant(StreamingContextStates.All))));
            notTrackedExpressions.Add(SerializationCallbacksHelper.GenerateCallIDeserializationExpression(type, newInstance));

            return(Deserializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                         inputStream,
                                                                         objTracker,
                                                                         newInstance,
                                                                         notTrackedExpressions,
                                                                         trackType,
                                                                         variables));
        }
        /// <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));
        }
示例#7
0
        public static Expression GenerateDictionaryGenericExpression(Type type,
                                                                     List <ParameterExpression> variables,
                                                                     ParameterExpression inputStream,
                                                                     ParameterExpression objTracker)
        {
            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 newInstance           = Expression.Parameter(type, "newInstanceDict");
            var comparerType          = Expression.Parameter(typeof(byte), "comparerType");

            var typeExpr     = Expression.Parameter(typeof(TypeWithHashCode), "typeExpr");
            var typeName     = Expression.Parameter(typeof(string), "typeName");
            var typeHashCode = Expression.Parameter(typeof(int), "typeHashCode");
            var deserializer = Expression.Parameter(typeof(Func <Stream, DeserializerObjectTracker, object>), "deserializer");

            variables.Add(deserializer);
            variables.Add(typeExpr);
            variables.Add(typeName);
            variables.Add(typeHashCode);


            variables.Add(newInstance);
            variables.Add(comparerType);

            var genericDictionaryType = DictionaryHelper.GetDictionaryType(type);
            var comparerConstructor   = DictionaryHelper.GetComparerConstructor(type);

            var deserializeDictionaryWithDefaultComparer = DeserializeDictionary(type,
                                                                                 genericDictionaryType,
                                                                                 variables,
                                                                                 newInstance,
                                                                                 inputStream,
                                                                                 objTracker,
                                                                                 deserializer,
                                                                                 typeExpr,
                                                                                 typeName,
                                                                                 typeHashCode,
                                                                                 (exprs, newIns) => exprs.Add(Expression.Assign(newIns, Expression.New(type.GetConstructor(new Type[0])))));

            if (comparerConstructor == null)
            {
                notTrackedExpressions.Add(PrimitiveHelpers.ReadByte(inputStream, objTracker));
                notTrackedExpressions.Add(deserializeDictionaryWithDefaultComparer);
            }
            else
            {
                notTrackedExpressions.Add(Expression.IfThenElse(Expression.Equal(PrimitiveHelpers.ReadByte(inputStream, objTracker), Expression.Constant(0, typeof(int))),
                                                                deserializeDictionaryWithDefaultComparer,
                                                                DeserializeDictionary(type,
                                                                                      genericDictionaryType,
                                                                                      variables,
                                                                                      newInstance,
                                                                                      inputStream,
                                                                                      objTracker,
                                                                                      deserializer,
                                                                                      typeExpr,
                                                                                      typeName,
                                                                                      typeHashCode,
                                                                                      (exprs, newIns) =>
                {
                    var eqType   = typeof(IEqualityComparer <>).MakeGenericType(genericDictionaryType.GetGenericArguments()[0]);
                    var comparer = Expression.Parameter(eqType, "comparer");
                    variables.Add(comparer);
                    exprs.Add(Deserializer.GetReadClassExpression(inputStream,
                                                                  objTracker,
                                                                  comparer,
                                                                  typeExpr,
                                                                  typeName,
                                                                  typeHashCode,
                                                                  deserializer,
                                                                  eqType));
                    exprs.Add(Expression.Assign(newIns, Expression.New(comparerConstructor, comparer)));
                })));
            }



            return(Deserializer.GenerateNullTrackedOrUntrackedExpression(type,
                                                                         inputStream,
                                                                         objTracker,
                                                                         newInstance,
                                                                         notTrackedExpressions,
                                                                         comparerType,
                                                                         variables));
        }