public void ReadStructureStampIfNeeded(ObjectReader reader, VersionToleranceLevel versionToleranceLevel, bool forceStampVerification = false) { if (StampHelpers.IsStampNeeded(this, reader.TreatCollectionAsUserObject)) { ReadStructureStamp(reader, versionToleranceLevel, forceStampVerification); } }
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)); }
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; }
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); }
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)); }
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)); }
/// <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); } }
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; }
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); }
/// <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; }
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; } }
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); }
/// <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<T, object> 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); }
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); }
/// <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<T, object> 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; }
/// <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); }
/// <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; }
/// <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); }
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); } }
public TypeStampReader(PrimitiveReader reader, VersionToleranceLevel versionToleranceLevel) { this.reader = reader; this.versionToleranceLevel = versionToleranceLevel; stampCache = new Dictionary<Type, List<FieldInfoOrEntryToOmit>>(); }