Exemple #1
0
 public void ReadStructureStampIfNeeded(ObjectReader reader, VersionToleranceLevel versionToleranceLevel, bool forceStampVerification = false)
 {
     if (StampHelpers.IsStampNeeded(this, reader.TreatCollectionAsUserObject))
     {
         ReadStructureStamp(reader, versionToleranceLevel, forceStampVerification);
     }
 }
Exemple #2
0
 public void ReadStructureStampIfNeeded(ObjectReader reader, VersionToleranceLevel versionToleranceLevel)
 {
     if (StampHelpers.IsStampNeeded(this, reader.TreatCollectionAsUserObject))
     {
         ReadStructureStamp(reader, versionToleranceLevel);
     }
 }
 public Settings GetSettings(VersionToleranceLevel level = 0)
 {
     return(new Settings(useGeneratedSerializer ? Method.Generated : Method.Reflection,
                         useGeneratedDeserializer ? Method.Generated : Method.Reflection,
                         level,
                         disableTypeStamping: !useStamping));
 }
Exemple #4
0
        public ObjectReader(Stream stream,
                            Serializer.ReadMethods readMethods,
                            SwapList objectsForSurrogates,
                            IDictionary <Type, Recipe> recipes,
                            Action <object> postDeserializationCallback,
                            bool treatCollectionAsUserObject,
                            VersionToleranceLevel versionToleranceLevel,
                            bool useBuffering,
                            bool disableStamping,
                            ReferencePreservation referencePreservation,
                            bool forceStampVerification)
        {
            this.readMethods = readMethods;
            this.postDeserializationCallback = postDeserializationCallback;
            this.treatCollectionAsUserObject = treatCollectionAsUserObject;
            this.referencePreservation       = referencePreservation;
            this.objectsForSurrogates        = objectsForSurrogates;
            this.recipes = recipes;

            VersionToleranceLevel = versionToleranceLevel;
            types      = new List <TypeDescriptor>();
            Methods    = new IdentifiedElementsList <MethodDescriptor>(this);
            Assemblies = new IdentifiedElementsList <AssemblyDescriptor>(this);
            Modules    = new IdentifiedElementsList <ModuleDescriptor>(this);
            HashCodeBasedWaitingValues   = new Dictionary <int, (object Dictionary, object Value)>();
            latePostDeserializationHooks = new List <Action>();

            reader = new PrimitiveReader(stream, useBuffering);
            surrogatesWhileReading = new OneToOneMap <int, object>();

            readTypeMethod         = disableStamping ? (Func <TypeDescriptor>)ReadSimpleTypeDescriptor : ReadFullTypeDescriptor;
            ForceStampVerification = forceStampVerification;
        }
 public void ReadStructureStampIfNeeded(ObjectReader reader, VersionToleranceLevel versionToleranceLevel)
 {
     if(StampHelpers.IsStampNeeded(this, reader.TreatCollectionAsUserObject))
     {
         ReadStructureStamp(reader, versionToleranceLevel);
     }
 }
        public ObjectReader(Stream stream, Serializer.ReadMethods readMethods, SwapList objectsForSurrogates = null, Action <object> postDeserializationCallback = null,
                            bool treatCollectionAsUserObject            = false,
                            VersionToleranceLevel versionToleranceLevel = 0, bool useBuffering = true, bool disableStamping = false,
                            ReferencePreservation referencePreservation = ReferencePreservation.Preserve,
                            bool forceStampVerification = false)
        {
            this.readMethods = readMethods;
            this.postDeserializationCallback = postDeserializationCallback;
            this.treatCollectionAsUserObject = treatCollectionAsUserObject;
            this.referencePreservation       = referencePreservation;
            this.objectsForSurrogates        = objectsForSurrogates ?? new SwapList();

            VersionToleranceLevel = versionToleranceLevel;
            types      = new List <TypeDescriptor>();
            Methods    = new IdentifiedElementsList <MethodDescriptor>(this);
            Assemblies = new IdentifiedElementsList <AssemblyDescriptor>(this);
            Modules    = new IdentifiedElementsList <ModuleDescriptor>(this);
            latePostDeserializationHooks = new List <Action>();

            reader = new PrimitiveReader(stream, useBuffering);
            surrogatesWhileReading = new OneToOneMap <int, object>();

            readTypeMethod         = disableStamping ? (Func <TypeDescriptor>)ReadSimpleTypeDescriptor : ReadFullTypeDescriptor;
            ForceStampVerification = forceStampVerification;
        }
Exemple #7
0
        public void TestSimpleFieldAddition(
            [Values(VersionToleranceLevel.Exact, VersionToleranceLevel.FieldAddition, VersionToleranceLevel.FieldAdditionAndRemoval)] VersionToleranceLevel versionToleranceLevel)
        {
            var fields = new List <Tuple <string, Type> >();

            fields.Add(Tuple.Create(Field1Name, typeof(int)));
            testsOnDomain1.BuildTypeOnAppDomain(TypeName, fields, false);
            var fieldCheck = new FieldCheck(Field1Name, 666);

            testsOnDomain1.SetValueOnAppDomain(fieldCheck);
            var data = testsOnDomain1.SerializeOnAppDomain();

            fields.Add(Tuple.Create(Field2Name, typeof(int)));
            testsOnDomain2.BuildTypeOnAppDomain(TypeName, fields, true);

            TestDelegate deserialization = () => testsOnDomain2.DeserializeOnAppDomain(data, new [] { fieldCheck, new FieldCheck(Field2Name, 0) }, GetSettings(versionToleranceLevel));

            if (versionToleranceLevel == VersionToleranceLevel.Exact)
            {
                Assert.Throws <InvalidOperationException>(deserialization);
            }
            else
            {
                deserialization();
            }
        }
 public bool Equals(ModuleDescriptor obj, VersionToleranceLevel versionToleranceLevel)
 {
     if (versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowGuidChange))
     {
         return(obj != null && obj.Name == Name && ModuleAssembly.Equals(obj.ModuleAssembly, versionToleranceLevel));
     }
     return(obj != null && obj.GUID == GUID && ModuleAssembly.Equals(obj.ModuleAssembly, versionToleranceLevel));
 }
 protected Settings GetSettings(VersionToleranceLevel level = 0)
 {
     return(new Settings(useGeneratedSerializer ? Method.Generated : Method.Reflection,
                         useGeneratedDeserializer ? Method.Generated : Method.Reflection,
                         level,
                         supportForISerializable,
                         treatCollectionsAsUserObjects));
 }
 public bool Equals(ModuleDescriptor obj, VersionToleranceLevel versionToleranceLevel)
 {
     if(versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowGuidChange))
     {
         return obj != null && obj.Name == Name && ModuleAssembly.Equals(obj.ModuleAssembly, versionToleranceLevel);
     }
     return obj != null && obj.GUID == GUID && ModuleAssembly.Equals(obj.ModuleAssembly, versionToleranceLevel);
 }
Exemple #11
0
        public bool Equals(AssemblyDescriptor obj, VersionToleranceLevel versionToleranceLevel)
        {
            if (versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowAssemblyVersionChange))
            {
                return(obj.Name == Name && obj.CultureName == CultureName && obj.Token.SequenceEqual(Token));
            }

            return(Equals(obj));
        }
 protected Settings GetSettings(VersionToleranceLevel level = 0)
 {
     return(new Settings(useGeneratedSerializer ? Method.Generated : Method.Reflection,
                         useGeneratedDeserializer ? Method.Generated : Method.Reflection,
                         level,
                         supportForIXmlSerializable,
                         treatCollectionsAsUserObjects,
                         disableTypeStamping: !useTypeStamping,
                         forceStampVerification: forceStampVerification));
 }
Exemple #13
0
        public bool Equals(TypeDescriptor obj, VersionToleranceLevel versionToleranceLevel)
        {
            if (versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowAssemblyVersionChange))
            {
                return(obj.UnderlyingType.FullName == UnderlyingType.FullName &&
                       obj.TypeAssembly.Equals(TypeAssembly, versionToleranceLevel));
            }

            return(Equals(obj));
        }
Exemple #14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Antmicro.Migrant.Customization.Settings"/> class.
 /// </summary>
 /// <param name='serializationMethod'>
 /// Method used for serialization.
 /// </param>
 /// <param name='deserializationMethod'>
 /// Method used for deserialization.
 /// </param>
 /// <param name='versionTolerance'>
 /// Specifies the possible level of difference between class layout when it was serialized and in the
 /// moment of deserialization.
 /// </param>
 /// <param name = "treatCollectionAsUserObject">
 /// Specifies if collection objects are to be deserialized without optimization (treated as normal user objects).
 /// </param>
 /// <param name = "supportForISerializable">
 /// Specifies whether Migrant should use GetObjectData approach for serialization.
 /// </param>
 /// <param name="useBuffering">
 /// True if buffering should be used, false if writes should directly go to the stream and reads should never read
 /// data in advance. Disabling buffering also disables padding.
 /// </param>
 /// <param name="referencePreservation">
 /// Tells serializer how to treat references between sessions of open stream serialization.
 /// </param>
 public Settings(Method serializationMethod   = Method.Generated, Method deserializationMethod = Method.Generated, VersionToleranceLevel versionTolerance = 0,
                 bool supportForISerializable = false, bool treatCollectionAsUserObject        = false, bool useBuffering = true,
                 ReferencePreservation referencePreservation = ReferencePreservation.Preserve)
 {
     SerializationMethod         = serializationMethod;
     DeserializationMethod       = deserializationMethod;
     VersionTolerance            = versionTolerance;
     SupportForISerializable     = supportForISerializable;
     TreatCollectionAsUserObject = treatCollectionAsUserObject;
     UseBuffering          = useBuffering;
     ReferencePreservation = referencePreservation;
 }
        public void ReadStructureStampIfNeeded(ObjectReader reader, VersionToleranceLevel versionToleranceLevel, bool forceStampVerification = false)
        {
            if (reader.recipes.ContainsKey(UnderlyingType))
            {
                // We do not need full stamp for recipe types.
                return;
            }

            if (StampHelpers.IsStampNeeded(this, reader.TreatCollectionAsUserObject))
            {
                ReadStructureStamp(reader, versionToleranceLevel, forceStampVerification);
            }
        }
Exemple #16
0
        private void ReadStructureStamp(ObjectReader reader, VersionToleranceLevel versionToleranceLevel)
        {
            baseType = reader.ReadType();
            var noOfFields = reader.PrimitiveReader.ReadInt32();

            for (int i = 0; i < noOfFields; i++)
            {
                var fieldDescriptor = new FieldDescriptor(this);
                fieldDescriptor.ReadFrom(reader);
                fields.Add(fieldDescriptor);
            }
            FieldsToDeserialize   = VerifyStructure(versionToleranceLevel);
            cache[UnderlyingType] = this;
        }
Exemple #17
0
        public void TestGuidVerification(
            [Values(VersionToleranceLevel.InheritanceChainChange,
                    VersionToleranceLevel.ExactLayout,
                    VersionToleranceLevel.FieldAddition,
                    VersionToleranceLevel.FieldMove,
                    VersionToleranceLevel.FieldRemoval,
                    VersionToleranceLevel.Guid,
                    VersionToleranceLevel.TypeNameChanged)] VersionToleranceLevel vtl)
        {
            var type   = DynamicClass.Create("A").WithField <int>("Field");
            var result = SerializeAndDeserializeOnTwoAppDomains(type, type, vtl);

            Assert.IsTrue(vtl.HasFlag(VersionToleranceLevel.Guid) ? !result : result);
        }
        public void TestGuidVerification(
            [Values(
                 0,
                 VersionToleranceLevel.AllowInheritanceChainChange,
                 VersionToleranceLevel.AllowFieldAddition,
                 VersionToleranceLevel.AllowFieldRemoval,
                 VersionToleranceLevel.AllowGuidChange
                 )] VersionToleranceLevel vtl)
        {
            var type   = DynamicType.CreateClass("A").WithField <int>("Field");
            var result = SerializeAndDeserializeOnTwoAppDomains(type, type, vtl, false);

            Assert.AreEqual(vtl.HasFlag(VersionToleranceLevel.AllowGuidChange), result);
        }
Exemple #19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Antmicro.Migrant.Customization.Settings"/> class.
 /// </summary>
 /// <param name='serializationMethod'>
 /// Method used for serialization.
 /// </param>
 /// <param name='deserializationMethod'>
 /// Method used for deserialization.
 /// </param>
 /// <param name='versionTolerance'>
 /// Specifies the possible level of difference between class layout when it was serialized and in the
 /// moment of deserialization.
 /// </param>
 /// <param name = "treatCollectionAsUserObject">
 /// Specifies if collection objects are to be deserialized without optimization (treated as normal user objects).
 /// </param>
 /// <param name = "supportForISerializable">
 /// Specifies whether Migrant should use GetObjectData approach for serialization.
 /// </param>
 /// <param name="supportForIXmlSerializable"> 
 /// Specifies whether Migrant should use xml serialization on objects implementing IXmlSerializable.
 /// </param>
 /// <param name="useBuffering"> 
 /// True if buffering should be used, false if writes should directly go to the stream and reads should never read
 /// data in advance. Disabling buffering also disables padding.
 /// </param>
 /// <param name="disableTypeStamping"> 
 /// Specifies if type stamping should be disabled in order to improve performance and limit output stream size.
 /// </param>
 /// <param name="referencePreservation"> 
 /// Tells serializer how to treat references between sessions of open stream serialization.
 /// </param>
 public Settings(Method serializationMethod = Method.Generated, Method deserializationMethod = Method.Generated, VersionToleranceLevel versionTolerance = 0,
                 bool supportForISerializable = false, bool supportForIXmlSerializable = false, bool treatCollectionAsUserObject = false,
                 bool useBuffering = true, bool disableTypeStamping = false, ReferencePreservation referencePreservation = ReferencePreservation.Preserve)
 {
     SerializationMethod = serializationMethod;
     DeserializationMethod = deserializationMethod;
     VersionTolerance = versionTolerance;
     SupportForISerializable = supportForISerializable;
     SupportForIXmlSerializable = supportForIXmlSerializable;
     TreatCollectionAsUserObject = treatCollectionAsUserObject;
     UseBuffering = useBuffering;
     ReferencePreservation = referencePreservation;
     DisableTypeStamping = disableTypeStamping;
 }
        private void ReadStructureStamp(ObjectReader reader, VersionToleranceLevel versionToleranceLevel, bool forceStampVerification)
        {
            baseType = (TypeFullDescriptor)reader.ReadType();
            var noOfFields = reader.PrimitiveReader.ReadInt32();

            for (int i = 0; i < noOfFields; i++)
            {
                var fieldDescriptor = new FieldDescriptor(this);
                fieldDescriptor.ReadFrom(reader);
                fields.Add(fieldDescriptor);
            }
            FieldsToDeserialize = VerifyStructure(versionToleranceLevel, forceStampVerification);
            // TODO: do we need this line?
            fullCache[UnderlyingType] = this;
        }
Exemple #21
0
        public void TestSimpleFieldRemoval(
            [Values(VersionToleranceLevel.InheritanceChainChange,
                    VersionToleranceLevel.ExactLayout,
                    VersionToleranceLevel.FieldAddition,
                    VersionToleranceLevel.FieldMove,
                    VersionToleranceLevel.FieldRemoval,
                    VersionToleranceLevel.Guid,
                    VersionToleranceLevel.TypeNameChanged)] VersionToleranceLevel vtl)
        {
            var type1             = DynamicClass.Create("A").WithField <int>("a").WithField <float>("b");
            var type2             = DynamicClass.Create("A").WithField <int>("a");
            var deserializationOK = SerializeAndDeserializeOnTwoAppDomains(type1, type2, vtl);

            Assert.IsTrue(vtl.HasFlag(VersionToleranceLevel.FieldRemoval) ? deserializationOK : !deserializationOK);
        }
        public void TestSimpleFieldRemoval(
            [Values(
                 0,
                 VersionToleranceLevel.AllowInheritanceChainChange,
                 VersionToleranceLevel.AllowFieldAddition,
                 VersionToleranceLevel.AllowFieldRemoval,
                 VersionToleranceLevel.AllowGuidChange
                 )] VersionToleranceLevel vtl)
        {
            var type1             = DynamicType.CreateClass("A").WithField <int>("a").WithField <float>("b");
            var type2             = DynamicType.CreateClass("A").WithField <int>("a");
            var deserializationOK = SerializeAndDeserializeOnTwoAppDomains(type1, type2, vtl);

            Assert.IsTrue(vtl.HasFlag(VersionToleranceLevel.AllowFieldRemoval) ? deserializationOK : !deserializationOK);
        }
        public void TestBaseClassInsertion(
            [Values(
                 0,
                 VersionToleranceLevel.AllowInheritanceChainChange,
                 VersionToleranceLevel.AllowFieldAddition,
                 VersionToleranceLevel.AllowFieldRemoval,
                 VersionToleranceLevel.AllowGuidChange
                 )] VersionToleranceLevel vtl)
        {
            var deserializationOK = SerializeAndDeserializeOnTwoAppDomains(
                DynamicType.CreateClass("A"),
                DynamicType.CreateClass("A", DynamicType.CreateClass("BaseA")),
                vtl);

            Assert.AreEqual(vtl.HasFlag(VersionToleranceLevel.AllowInheritanceChainChange), deserializationOK);
        }
        public void TestBaseClassRemoval(
            [Values(
                 0,
                 VersionToleranceLevel.AllowInheritanceChainChange,
                 VersionToleranceLevel.AllowFieldAddition,
                 VersionToleranceLevel.AllowFieldRemoval,
                 VersionToleranceLevel.AllowGuidChange
                 )] VersionToleranceLevel vtl)
        {
            var deserializationOK = SerializeAndDeserializeOnTwoAppDomains(
                DynamicType.CreateClass("A", DynamicType.CreateClass("BaseA")),
                DynamicType.CreateClass("A", additionalTypes: new [] { DynamicType.CreateClass("BaseA") }),
                vtl);

            Assert.IsTrue(vtl.HasFlag(VersionToleranceLevel.AllowInheritanceChainChange) ? deserializationOK : !deserializationOK);
        }
        public bool SerializeAndDeserializeOnTwoAppDomains(DynamicType domainOneType, DynamicType domainTwoType, VersionToleranceLevel vtl, bool allowGuidChange = true)
        {
            testsOnDomain1.CreateInstanceOnAppDomain(domainOneType);
            testsOnDomain2.CreateInstanceOnAppDomain(domainTwoType);

            var bytes = testsOnDomain1.SerializeOnAppDomain();
            try 
            {
                testsOnDomain2.DeserializeOnAppDomain(bytes, settings.GetSettings(allowGuidChange ? vtl | VersionToleranceLevel.AllowGuidChange : vtl));
                return true;
            } 
            catch (VersionToleranceException)
            {
                return false;
            }
        }
Exemple #26
0
        public void TestBaseClassRemoval(
            [Values(VersionToleranceLevel.InheritanceChainChange,
                    VersionToleranceLevel.ExactLayout,
                    VersionToleranceLevel.FieldAddition,
                    VersionToleranceLevel.FieldMove,
                    VersionToleranceLevel.FieldRemoval,
                    VersionToleranceLevel.Guid,
                    VersionToleranceLevel.TypeNameChanged)] VersionToleranceLevel vtl)
        {
            var deserializationOK = SerializeAndDeserializeOnTwoAppDomains(
                DynamicClass.Create("A", DynamicClass.Create("BaseA")),
                DynamicClass.Create("A"),
                vtl);

            Assert.IsTrue(vtl.HasFlag(VersionToleranceLevel.InheritanceChainChange) ? deserializationOK : !deserializationOK);
        }
        public void TestFieldMovedBetweenClasses(
            [Values(
                 VersionToleranceLevel.AllowInheritanceChainChange,
                 VersionToleranceLevel.AllowFieldAddition,
                 VersionToleranceLevel.AllowFieldRemoval,
                 VersionToleranceLevel.AllowGuidChange,
                 VersionToleranceLevel.AllowFieldAddition | VersionToleranceLevel.AllowFieldRemoval
                 )] VersionToleranceLevel vtl)
        {
            var deserializationOK = SerializeAndDeserializeOnTwoAppDomains(
                DynamicType.CreateClass("A", DynamicType.CreateClass("BaseA").WithField("a", typeof(string))).WithField("b", typeof(int)),
                DynamicType.CreateClass("A", DynamicType.CreateClass("BaseA")).WithField("a", typeof(string)).WithField("b", typeof(int)),
                vtl);

            Assert.AreEqual(
                vtl.HasFlag(VersionToleranceLevel.AllowFieldAddition) && vtl.HasFlag(VersionToleranceLevel.AllowFieldRemoval),
                deserializationOK);
        }
Exemple #28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Antmicro.Migrant.ObjectReader" /> class.
 /// </summary>
 /// <param name='stream'>
 /// Stream from which objects will be read.
 /// </param>
 /// <param name='objectsForSurrogates'>
 /// Dictionary, containing callbacks that provide objects for given type of surrogate. Callbacks have to be of type Func&lt;T, object&gt; where
 /// typeof(T) is type of surrogate.
 /// </param>
 /// <param name='postDeserializationCallback'>
 /// Callback which will be called after deserialization of every unique object. Deserialized
 /// object is given in the callback's only parameter.
 /// </param>
 /// <param name='readMethods'>
 /// Cache in which generated read methods are stored and reused between instances of <see cref="Antmicro.Migrant.ObjectReader" />.
 /// Can be null if one does not want to use the cache.
 /// </param>
 /// <param name='isGenerating'>
 /// True if read methods are to be generated, false if one wants to use reflection.
 /// </param>
 /// <param name = "treatCollectionAsUserObject">
 /// True if collection objects are to be deserialized without optimization (treated as normal user objects).
 /// </param>
 /// <param name="versionToleranceLevel">
 /// Describes the tolerance level of this reader when handling discrepancies in type description (new or missing fields, etc.).
 /// </param>
 /// <param name="useBuffering">
 /// True if buffering was used with the corresponding ObjectWriter or false otherwise - i.e. when no padding and buffering is used.
 /// </param>
 /// <param name="referencePreservation">
 /// Tells deserializer whether open stream serialization preserved objects identieties between serialization. Note that this option should
 /// be consistent with what was used during serialization.
 /// </param>
 public ObjectReader(Stream stream, InheritanceAwareList <Delegate> objectsForSurrogates = null, Action <object> postDeserializationCallback = null,
                     IDictionary <Type, DynamicMethod> readMethods = null, bool isGenerating = false, bool treatCollectionAsUserObject = false,
                     VersionToleranceLevel versionToleranceLevel   = 0, bool useBuffering    = true,
                     ReferencePreservation referencePreservation   = ReferencePreservation.Preserve)
 {
     if (objectsForSurrogates == null)
     {
         objectsForSurrogates = new InheritanceAwareList <Delegate>();
     }
     this.objectsForSurrogates        = objectsForSurrogates;
     this.readMethodsCache            = readMethods ?? new Dictionary <Type, DynamicMethod>();
     this.useGeneratedDeserialization = isGenerating;
     typeList   = new List <Type>();
     methodList = new List <MethodInfo>();
     postDeserializationHooks         = new List <Action>();
     this.postDeserializationCallback = postDeserializationCallback;
     this.treatCollectionAsUserObject = treatCollectionAsUserObject;
     delegatesCache             = new Dictionary <Type, Func <int, object> >();
     reader                     = new PrimitiveReader(stream, useBuffering);
     stamper                    = new TypeStampReader(reader, versionToleranceLevel);
     this.referencePreservation = referencePreservation;
 }
        public CompareResult CompareWith(FieldDescriptor fd, VersionToleranceLevel versionToleranceLevel)
        {
            if (fd.Name == Name)
            {
                if (!fd.FieldType.Equals(FieldType, versionToleranceLevel))
                {
                    return(CompareResult.FieldTypeChanged);
                }
            }
            else if (fd.FieldType.Equals(FieldType))
            {
                if (fd.Name != Name)
                {
                    return(CompareResult.FieldRenamed);
                }
            }
            else
            {
                return(CompareResult.NotMatch);
            }

            return(CompareResult.Match);
        }
Exemple #30
0
        public TypeDescriptorCompareResult CompareWith(TypeDescriptor previous, VersionToleranceLevel versionToleranceLevel = 0)
        {
            var result = new TypeDescriptorCompareResult();

            var prevFields = previous.fields.ToDictionary(x => x.FullName, x => x);

            foreach (var field in fields.Where(f => !f.IsTransient))
            {
                FieldDescriptor currentField;
                if (!prevFields.TryGetValue(field.FullName, out currentField))
                {
                    // field is missing in the previous version of the class
                    result.FieldsAdded.Add(field);
                    continue;
                }
                // are the types compatible?
                var compareResult = currentField.CompareWith(field, versionToleranceLevel);
                if (compareResult != FieldDescriptor.CompareResult.Match)
                {
                    result.FieldsChanged.Add(field);
                }

                // why do we remove a field from current ones? if some field is still left after our operation, then field addition occured
                // we have to check that, cause it can be illegal from the version tolerance point of view
                prevFields.Remove(field.FullName);
            }

            // result should also contain transient fields, because some of them may
            // be marked with the [Constructor] attribute
            foreach (var nonTransient in prevFields.Values.Where(x => !x.IsTransient))
            {
                result.FieldsRemoved.Add(nonTransient);
            }

            return(result);
        }
Exemple #31
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AntMicro.Migrant.ObjectReader" /> class.
 /// </summary>
 /// <param name='stream'>
 /// Stream from which objects will be read.
 /// </param>
 /// <param name='objectsForSurrogates'>
 /// Dictionary, containing callbacks that provide objects for given type of surrogate. Callbacks have to be of type Func&lt;T, object&gt; where
 /// typeof(T) is type of surrogate.
 /// </param>
 /// <param name='postDeserializationCallback'>
 /// Callback which will be called after deserialization of every unique object. Deserialized
 /// object is given in the callback's only parameter.
 /// </param>
 /// <param name='readMethods'>
 /// Cache in which generated read methods are stored and reused between instances of <see cref="AntMicro.Migrant.ObjectReader" />.
 /// Can be null if one does not want to use the cache.
 /// </param>
 /// <param name='isGenerating'>
 /// True if read methods are to be generated, false if one wants to use reflection.
 /// </param>
 /// <param name="versionToleranceLevel">
 /// Describes the tolerance level of this reader when handling discrepancies in type description (new or missing fields, etc.).
 /// </param>
 public ObjectReader(Stream stream, IDictionary <Type, Delegate> objectsForSurrogates = null, Action <object> postDeserializationCallback = null,
                     IDictionary <Type, DynamicMethod> readMethods = null, bool isGenerating = false, VersionToleranceLevel versionToleranceLevel = 0)
 {
     if (objectsForSurrogates == null)
     {
         objectsForSurrogates = new Dictionary <Type, Delegate>();
     }
     this.objectsForSurrogates        = objectsForSurrogates;
     this.readMethodsCache            = readMethods ?? new Dictionary <Type, DynamicMethod>();
     this.useGeneratedDeserialization = isGenerating;
     typeList   = new List <Type>();
     methodList = new List <MethodInfo>();
     postDeserializationHooks = new List <Action>();
     this.stream = stream;
     this.postDeserializationCallback = postDeserializationCallback;
     this.versionToleranceLevel       = versionToleranceLevel;
     PrepareForTheRead();
 }
 private void ReadStructureStamp(ObjectReader reader, VersionToleranceLevel versionToleranceLevel)
 {
     baseType = (TypeFullDescriptor)reader.ReadType();
     var noOfFields = reader.PrimitiveReader.ReadInt32();
     for(int i = 0; i < noOfFields; i++)
     {
         var fieldDescriptor = new FieldDescriptor(this);
         fieldDescriptor.ReadFrom(reader);
         fields.Add(fieldDescriptor);
     }
     FieldsToDeserialize = VerifyStructure(versionToleranceLevel);
     // TODO: do we need this line?
     fullCache[UnderlyingType] = this;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="Antmicro.Migrant.Customization.Settings"/> class.
 /// </summary>
 /// <param name='serializationMethod'>
 /// Method used for serialization.
 /// </param>
 /// <param name='deserializationMethod'>
 /// Method used for deserialization.
 /// </param>
 /// <param name='versionTolerance'>
 /// Specifies the possible level of difference between class layout when it was serialized and in the
 /// moment of deserialization.
 /// </param>
 /// <param name = "treatCollectionAsUserObject">
 /// Specifies if collection objects are to be deserialized without optimization (treated as normal user objects).
 /// </param>
 /// <param name = "supportForISerializable">
 /// Specifies whether Migrant should use GetObjectData approach for serialization.
 /// </param>
 /// <param name="useBuffering"> 
 /// True if buffering should be used, false if writes should directly go to the stream and reads should never read
 /// data in advance. Disabling buffering also disables padding.
 /// </param>
 /// <param name="disableTypeStamping"> 
 /// Specifies if type stamping should be disabled in order to improve performance and limit output stream size.
 /// </param>
 /// <param name="referencePreservation"> 
 /// Tells serializer how to treat references between sessions of open stream serialization.
 /// </param>
 public Settings With(Method serializationMethod = Method.Generated, Method deserializationMethod = Method.Generated, VersionToleranceLevel versionTolerance = 0,
                      bool supportForISerializable = false, bool treatCollectionAsUserObject = false, bool useBuffering = true, bool disableTypeStamping = false,
                      ReferencePreservation referencePreservation = ReferencePreservation.Preserve)
 {
     var result = new Settings {
         SerializationMethod = serializationMethod,
         DeserializationMethod = deserializationMethod,
         VersionTolerance = versionTolerance,
         SupportForISerializable = supportForISerializable,
         TreatCollectionAsUserObject = treatCollectionAsUserObject,
         UseBuffering = useBuffering,
         DisableTypeStamping = disableTypeStamping,
         ReferencePreservation = referencePreservation
     };
     return result;
 }
        public bool Equals(AssemblyDescriptor obj, VersionToleranceLevel versionToleranceLevel)
        {
            if(versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowAssemblyVersionChange))
            {
                return obj.Name == Name && obj.CultureName == CultureName && obj.Token.SequenceEqual(Token);
            }

            return Equals(obj);
        }
        private List<FieldInfoOrEntryToOmit> VerifyStructure(VersionToleranceLevel versionToleranceLevel)
        {
            if(TypeModule.GUID == UnderlyingType.Module.ModuleVersionId)
            {
                return StampHelpers.GetFieldsInSerializationOrder(UnderlyingType, true).Select(x => new FieldInfoOrEntryToOmit(x)).ToList();
            }

            if(!versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowGuidChange))
            {
                throw new VersionToleranceException(string.Format("The class {2} was serialized with different module version id {0}, current one is {1}.",
                    TypeModule.GUID, UnderlyingType.Module.ModuleVersionId, UnderlyingType.FullName));
            }

            var result = new List<FieldInfoOrEntryToOmit>();

            var assemblyTypeDescriptor = ((TypeFullDescriptor)UnderlyingType);
            if( !(assemblyTypeDescriptor.baseType == null && baseType == null)
                && ((assemblyTypeDescriptor.baseType == null && baseType != null) || !assemblyTypeDescriptor.baseType.Equals(baseType)) 
                && !versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowInheritanceChainChange))
            {
                throw new VersionToleranceException(string.Format("Class hierarchy for {2} changed. Expected '{1}' as base class, but found '{0}'.", 
                    baseType != null ? baseType.UnderlyingType.FullName : "null", 
                    assemblyTypeDescriptor.baseType != null ? assemblyTypeDescriptor.baseType.UnderlyingType.FullName : "null",
                    UnderlyingType.FullName));
            }

            if(assemblyTypeDescriptor.TypeModule.ModuleAssembly.Version != TypeModule.ModuleAssembly.Version && !versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowAssemblyVersionChange))
            {
                throw new VersionToleranceException(string.Format("Assembly version changed from {0} to {1} for class {2}", 
                    TypeModule.ModuleAssembly.Version, assemblyTypeDescriptor.TypeModule.ModuleAssembly.Version, UnderlyingType.FullName));
            }

            var cmpResult = assemblyTypeDescriptor.CompareWith(this, versionToleranceLevel);

            if(cmpResult.FieldsChanged.Any())
            {
                throw new VersionToleranceException(string.Format("Field {0} type changed in class {1}.", cmpResult.FieldsChanged[0].Name, UnderlyingType.FullName));
            }

            if(cmpResult.FieldsAdded.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowFieldAddition))
            {
                throw new VersionToleranceException(string.Format("Field {0} added to class {1}.", cmpResult.FieldsAdded[0].Name, UnderlyingType.FullName));
            }
            if(cmpResult.FieldsRemoved.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowFieldRemoval))
            {
                throw new VersionToleranceException(string.Format("Field {0} removed from class {1}.", cmpResult.FieldsRemoved[0].Name, UnderlyingType.FullName));
            }

            foreach(var field in fields)
            {
                if(cmpResult.FieldsRemoved.Contains(field))
                {
                    result.Add(new FieldInfoOrEntryToOmit(field.FieldType.UnderlyingType));
                }
                else
                {
                    result.Add(new FieldInfoOrEntryToOmit(field.UnderlyingFieldInfo));
                }
            }

            foreach(var field in assemblyTypeDescriptor.GetConstructorRecreatedFields().Select(x => x.Field))
            {
                result.Add(new FieldInfoOrEntryToOmit(field));
            }

            return result;
        }
        public TypeDescriptorCompareResult CompareWith(TypeFullDescriptor previous, VersionToleranceLevel versionToleranceLevel = 0)
        {
            var result = new TypeDescriptorCompareResult();

            var prevFields = previous.fields.ToDictionary(x => x.FullName, x => x);
            foreach(var field in fields.Where(f => !f.IsTransient))
            {
                FieldDescriptor currentField;
                if(!prevFields.TryGetValue(field.FullName, out currentField))
                {
                    // field is missing in the previous version of the class
                    result.FieldsAdded.Add(field);
                    continue;
                }
                // are the types compatible?
                var compareResult = currentField.CompareWith(field, versionToleranceLevel);
                if(compareResult != FieldDescriptor.CompareResult.Match)
                {
                    result.FieldsChanged.Add(field);
                }

                // why do we remove a field from current ones? if some field is still left after our operation, then field addition occured
                // we have to check that, cause it can be illegal from the version tolerance point of view
                prevFields.Remove(field.FullName);
            }

            // result should also contain transient fields, because some of them may
            // be marked with the [Constructor] attribute
            foreach(var nonTransient in prevFields.Values.Where(x => !x.IsTransient))
            {
                result.FieldsRemoved.Add(nonTransient);
            }

            return result;
        }
Exemple #37
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AntMicro.Migrant.Customization.Settings"/> class.
 /// </summary>
 /// <param name='serializationMethod'>
 /// Method used for serialization.
 /// </param>
 /// <param name='deserializationMethod'>
 /// Method used for deserialization.
 /// </param>
 /// <param name='versionTolerance'>
 /// Specifies the possible level of difference between class layout when it was serialized and in the
 /// moment of deserialization.
 /// </param>
 public Settings(Method serializationMethod = Method.Generated, Method deserializationMethod = Method.Generated, VersionToleranceLevel versionTolerance = 0)
 {
     SerializationMethod   = serializationMethod;
     DeserializationMethod = deserializationMethod;
     VersionTolerance      = versionTolerance;
 }
 public Settings GetSettingsAllowingGuidChange(VersionToleranceLevel level = 0)
 {
     return GetSettings(level | VersionToleranceLevel.AllowGuidChange);
 }
 public Settings GetSettings(VersionToleranceLevel level = 0)
 {
     return new Settings(useGeneratedSerializer ? Method.Generated : Method.Reflection,
                         useGeneratedDeserializer ? Method.Generated : Method.Reflection,
                         level,
                         disableTypeStamping: !useStamping);
 }
Exemple #40
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Antmicro.Migrant.Customization.Settings"/> class.
 /// </summary>
 /// <param name='serializationMethod'>
 /// Method used for serialization.
 /// </param>
 /// <param name='deserializationMethod'>
 /// Method used for deserialization.
 /// </param>
 /// <param name='versionTolerance'>
 /// Specifies the possible level of difference between class layout when it was serialized and in the
 /// moment of deserialization.
 /// </param>
 /// <param name = "treatCollectionAsUserObject">
 /// Specifies if collection objects are to be deserialized without optimization (treated as normal user objects).
 /// </param>
 /// <param name = "supportForISerializable">
 /// Specifies whether Migrant should use GetObjectData approach for serialization.
 /// </param>
 /// <param name="useBuffering"> 
 /// True if buffering should be used, false if writes should directly go to the stream and reads should never read
 /// data in advance. Disabling buffering also disables padding.
 /// </param>
 /// <param name="disableTypeStamping"> 
 /// Specifies if type stamping should be disabled in order to improve performance and limit output stream size.
 /// </param>
 /// <param name="referencePreservation"> 
 /// Tells serializer how to treat references between sessions of open stream serialization.
 /// </param>
 public Settings With(Method? serializationMethod = null, Method? deserializationMethod = null, VersionToleranceLevel? versionTolerance = null,
                      bool? supportForISerializable = null, bool? treatCollectionAsUserObject = null, bool? useBuffering = null, bool? disableTypeStamping = null,
                      ReferencePreservation? referencePreservation = null)
 {
     var result = new Settings {
         SerializationMethod = serializationMethod ?? SerializationMethod,
         DeserializationMethod = deserializationMethod ?? DeserializationMethod,
         VersionTolerance = versionTolerance ?? VersionTolerance,
         SupportForISerializable = supportForISerializable ?? SupportForISerializable,
         TreatCollectionAsUserObject = treatCollectionAsUserObject ?? TreatCollectionAsUserObject,
         UseBuffering = useBuffering ?? UseBuffering,
         DisableTypeStamping = disableTypeStamping ?? DisableTypeStamping,
         ReferencePreservation = referencePreservation ?? ReferencePreservation
     };
     return result;
 }
Exemple #41
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Antmicro.Migrant.Customization.Settings"/> class.
        /// </summary>
        /// <param name='serializationMethod'>
        /// Method used for serialization.
        /// </param>
        /// <param name='deserializationMethod'>
        /// Method used for deserialization.
        /// </param>
        /// <param name='versionTolerance'>
        /// Specifies the possible level of difference between class layout when it was serialized and in the
        /// moment of deserialization.
        /// </param>
        /// <param name = "treatCollectionAsUserObject">
        /// Specifies if collection objects are to be deserialized without optimization (treated as normal user objects).
        /// </param>
        /// <param name = "supportForISerializable">
        /// Specifies whether Migrant should use GetObjectData approach for serialization.
        /// </param>
        /// <param name="useBuffering">
        /// True if buffering should be used, false if writes should directly go to the stream and reads should never read
        /// data in advance. Disabling buffering also disables padding.
        /// </param>
        /// <param name="referencePreservation">
        /// Tells serializer how to treat references between sessions of open stream serialization.
        /// </param>
        public Settings With(Method serializationMethod   = Method.Generated, Method deserializationMethod = Method.Generated, VersionToleranceLevel versionTolerance = 0,
                             bool supportForISerializable = false, bool treatCollectionAsUserObject        = false, bool useBuffering = true,
                             ReferencePreservation referencePreservation = ReferencePreservation.Preserve)
        {
            var result = new Settings {
                SerializationMethod         = serializationMethod,
                DeserializationMethod       = deserializationMethod,
                VersionTolerance            = versionTolerance,
                SupportForISerializable     = supportForISerializable,
                TreatCollectionAsUserObject = treatCollectionAsUserObject,
                UseBuffering          = useBuffering,
                ReferencePreservation = referencePreservation
            };

            return(result);
        }
        public bool Equals(TypeFullDescriptor obj, VersionToleranceLevel versionToleranceLevel)
        {
            if(versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowAssemblyVersionChange))
            {
                return obj.UnderlyingType.FullName == UnderlyingType.FullName
                    && obj.TypeModule.Equals(TypeModule, versionToleranceLevel);
            }

            return Equals(obj);
        }
Exemple #43
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AntMicro.Migrant.Customization.Settings"/> class.
 /// </summary>
 /// <param name='serializationMethod'>
 /// Method used for serialization.
 /// </param>
 /// <param name='deserializationMethod'>
 /// Method used for deserialization.
 /// </param>
 /// <param name='versionTolerance'>
 /// Specifies the possible level of difference between class layout when it was serialized and in the
 /// moment of deserialization.
 /// </param>
 public Settings(Method serializationMethod = Method.Generated, Method deserializationMethod = Method.Generated, VersionToleranceLevel versionTolerance = 0)
 {
     SerializationMethod = serializationMethod;
     DeserializationMethod = deserializationMethod;
     VersionTolerance = versionTolerance;
 }
 protected Settings GetSettings(VersionToleranceLevel level = 0)
 {
     return new Settings(useGeneratedSerializer ? Method.Generated : Method.Reflection,
                         useGeneratedDeserializer ? Method.Generated : Method.Reflection,
                         level);
 }
        public bool SerializeAndDeserializeOnTwoAppDomains(DynamicType domainOneType, DynamicType domainTwoType, VersionToleranceLevel vtl, bool allowGuidChange = true)
        {
            testsOnDomain1.CreateInstanceOnAppDomain(domainOneType);
            testsOnDomain2.CreateInstanceOnAppDomain(domainTwoType);

            var bytes = testsOnDomain1.SerializeOnAppDomain();

            try
            {
                testsOnDomain2.DeserializeOnAppDomain(bytes, settings.GetSettings(allowGuidChange ? vtl | VersionToleranceLevel.AllowGuidChange : vtl));
                return(true);
            }
            catch (VersionToleranceException)
            {
                return(false);
            }
        }
Exemple #46
0
 public TypeStampReader(PrimitiveReader reader, VersionToleranceLevel versionToleranceLevel)
 {
     this.reader = reader;
     this.versionToleranceLevel = versionToleranceLevel;
     stampCache = new Dictionary<Type, List<FieldInfoOrEntryToOmit>>();
 }