Ejemplo n.º 1
0
 public void WriteStructureStampIfNeeded(ObjectWriter writer)
 {
     if (StampHelpers.IsStampNeeded(this, writer.TreatCollectionAsUserObject))
     {
         WriteStructureStamp(writer);
     }
 }
Ejemplo n.º 2
0
 public void ReadStructureStampIfNeeded(ObjectReader reader, VersionToleranceLevel versionToleranceLevel, bool forceStampVerification = false)
 {
     if (StampHelpers.IsStampNeeded(this, reader.TreatCollectionAsUserObject))
     {
         ReadStructureStamp(reader, versionToleranceLevel, forceStampVerification);
     }
 }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
 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;
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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);
        }