public void WriteStructureStampIfNeeded(ObjectWriter writer) { if (StampHelpers.IsStampNeeded(this, writer.TreatCollectionAsUserObject)) { WriteStructureStamp(writer); } }
public void ReadStructureStampIfNeeded(ObjectReader reader, VersionToleranceLevel versionToleranceLevel, bool forceStampVerification = false) { if (StampHelpers.IsStampNeeded(this, reader.TreatCollectionAsUserObject)) { ReadStructureStamp(reader, versionToleranceLevel, forceStampVerification); } }
private void Init(Type t) { UnderlyingType = t; TypeModule = new ModuleDescriptor(t.Module); if (UnderlyingType.IsGenericType) { GenericFullName = UnderlyingType.GetGenericTypeDefinition().FullName; Name = UnderlyingType.GetGenericTypeDefinition().AssemblyQualifiedName; } else { Name = UnderlyingType.AssemblyQualifiedName; GenericFullName = UnderlyingType.FullName; } if (t.BaseType != null) { baseType = t.BaseType; } var fieldsToDeserialize = new List <FieldInfoOrEntryToOmit>(); foreach (var field in StampHelpers.GetFieldsInSerializationOrder(UnderlyingType, true)) { fieldsToDeserialize.Add(new FieldInfoOrEntryToOmit(field)); if (!field.IsTransient()) { fields.Add(new FieldDescriptor(field)); } } FieldsToDeserialize = fieldsToDeserialize; }
public void ReadStructureStampIfNeeded(ObjectReader reader, VersionToleranceLevel versionToleranceLevel) { if (StampHelpers.IsStampNeeded(this, reader.TreatCollectionAsUserObject)) { ReadStructureStamp(reader, versionToleranceLevel); } }
public TypeSimpleDescriptor(Type t) { UnderlyingType = t; Name = t.AssemblyQualifiedName; nameAsByteArray = Encoding.UTF8.GetBytes(Name); var fieldsToDeserialize = new List <FieldInfoOrEntryToOmit>(); foreach (var field in StampHelpers.GetFieldsInSerializationOrder(UnderlyingType, true)) { fieldsToDeserialize.Add(new FieldInfoOrEntryToOmit(field)); } FieldsToDeserialize = fieldsToDeserialize; }
public void Stamp(Type type) { if (!StampHelpers.IsStampNeeded(type, treatCollectionAsUserObject)) { return; } if (alreadyWritten.Contains(type)) { return; } alreadyWritten.Add(type); var ts = new TypeStamp(type); ts.WriteTo(writer); }
public void ReadStamp(Type type, bool treatCollectionAsUserObject) { if (!StampHelpers.IsStampNeeded(type, treatCollectionAsUserObject)) { return; } if (stampCache.ContainsKey(type)) { return; } var streamTypeStamp = new TypeStamp(); streamTypeStamp.ReadFrom(reader); if (streamTypeStamp.ModuleGUID == type.Module.ModuleVersionId) { stampCache.Add(type, StampHelpers.GetFieldsInSerializationOrder(type, true).Select(x => new FieldInfoOrEntryToOmit(x)).ToList()); return; } if (versionToleranceLevel == VersionToleranceLevel.Guid) { throw new InvalidOperationException(string.Format("The class was serialized with different module version id {0}, current one is {1}.", streamTypeStamp.ModuleGUID, type.Module.ModuleVersionId)); } var result = new List <FieldInfoOrEntryToOmit>(); var assemblyTypeStamp = new TypeStamp(type, true); if (assemblyTypeStamp.Classes.Count != streamTypeStamp.Classes.Count && !versionToleranceLevel.HasFlag(VersionToleranceLevel.InheritanceChainChange)) { throw new InvalidOperationException(string.Format("Class hierarchy changed. Expected {0} classes in a chain, but found {1}.", assemblyTypeStamp.Classes.Count, streamTypeStamp.Classes.Count)); } var cmpResult = assemblyTypeStamp.CompareWith(streamTypeStamp); if (cmpResult.ClassesRenamed.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.TypeNameChanged)) { if (versionToleranceLevel.HasFlag(VersionToleranceLevel.AssemblyVersionChanged)) { foreach (var renamed in cmpResult.ClassesRenamed) { var beforeStrippedVersion = Regex.Replace(renamed.Item1, "Version=[0-9.]*", string.Empty); var afterStrippedVersion = Regex.Replace(renamed.Item2, "Version=[0-9.]*", string.Empty); if (beforeStrippedVersion != afterStrippedVersion) { throw new InvalidOperationException(string.Format("Class name changed from {0} to {1}", cmpResult.ClassesRenamed[0].Item1, cmpResult.ClassesRenamed[0].Item2)); } } } else { throw new InvalidOperationException(string.Format("Class name changed from {0} to {1}", cmpResult.ClassesRenamed[0].Item1, cmpResult.ClassesRenamed[0].Item2)); } } if (cmpResult.FieldsAdded.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.FieldAddition)) { throw new InvalidOperationException(string.Format("Field added: {0}.", cmpResult.FieldsAdded[0].Name)); } if (cmpResult.FieldsRemoved.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.FieldRemoval)) { throw new InvalidOperationException(string.Format("Field removed: {0}.", cmpResult.FieldsRemoved[0].Name)); } if (cmpResult.FieldsMoved.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.FieldMove)) { throw new InvalidOperationException(string.Format("Field moved: {0}.", cmpResult.FieldsMoved.ElementAt(0).Key.Name)); } foreach (var field in streamTypeStamp.GetFieldsInAlphabeticalOrder()) { if (cmpResult.FieldsRemoved.Contains(field)) { result.Add(new FieldInfoOrEntryToOmit(Type.GetType(field.TypeAQN))); } else if (cmpResult.FieldsMoved.ContainsKey(field)) { var moved = cmpResult.FieldsMoved[field]; var finfo = Type.GetType(moved.OwningTypeAQN).GetField(moved.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); result.Add(new FieldInfoOrEntryToOmit(finfo)); } else { var finfo = Type.GetType(field.OwningTypeAQN).GetField(field.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); result.Add(new FieldInfoOrEntryToOmit(finfo)); } } foreach (var field in assemblyTypeStamp.GetFieldsInAlphabeticalOrder().Where(x => x.IsConstructor)) { var finfo = Type.GetType(field.OwningTypeAQN).GetField(field.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); result.Add(new FieldInfoOrEntryToOmit(finfo)); } stampCache.Add(type, result); }
private List <FieldInfoOrEntryToOmit> VerifyStructure(VersionToleranceLevel versionToleranceLevel, bool forceStampVerification) { if (TypeModule.GUID != UnderlyingType.Module.ModuleVersionId) { 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)); } } else if (!forceStampVerification) { return(StampHelpers.GetFieldsInSerializationOrder(UnderlyingType, true).Select(x => new FieldInfoOrEntryToOmit(x)).ToList()); } 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); }