Beispiel #1
0
        private void UpdateFields(Type actualType, object target)
        {
            var fieldOrTypeInfos = TypeDescriptor.CreateFromType(actualType).FieldsToDeserialize;

            foreach (var fieldOrTypeInfo in fieldOrTypeInfos)
            {
                if (fieldOrTypeInfo.Field == null)
                {
                    ReadField(fieldOrTypeInfo.TypeToOmit);
                    continue;
                }
                var field = fieldOrTypeInfo.Field;
                if (field.IsDefined(typeof(TransientAttribute), false))
                {
                    if (field.IsDefined(typeof(ConstructorAttribute), false))
                    {
                        var ctorAttribute = (ConstructorAttribute)field.GetCustomAttributes(false).First(x => x is ConstructorAttribute);

                        field.SetValue(target, Activator.CreateInstance(field.FieldType, ctorAttribute.Parameters));
                    }
                    continue;
                }
                field.SetValue(target, ReadField(field.FieldType));
            }
        }
Beispiel #2
0
        public FieldDescriptor(FieldInfo finfo)
        {
            Name = finfo.Name;

            DeclaringType = TypeDescriptor.CreateFromType(finfo.DeclaringType);
            FieldType     = TypeDescriptor.CreateFromType(finfo.FieldType);
            IsTransient   = finfo.IsTransient();
            IsConstructor = finfo.IsConstructor();

            UnderlyingFieldInfo = finfo;
        }
Beispiel #3
0
        internal int TouchAndWriteTypeId(Type type)
        {
            var typeDescriptor = TypeDescriptor.CreateFromType(type);

            int typeId;

            if (typeIndices.ContainsKey(typeDescriptor))
            {
                typeId = typeIndices[typeDescriptor];
                writer.Write(typeId);
                return(typeId);
            }
            typeId = nextTypeId++;
            typeIndices.Add(typeDescriptor, typeId);
            writer.Write(typeId);
            typeDescriptor.WriteTypeStamp(this);
            typeDescriptor.WriteStructureStampIfNeeded(this);
            return(typeId);
        }
Beispiel #4
0
        private void Init(Type t)
        {
            UnderlyingType = t;

            TypeAssembly = AssemblyDescriptor.CreateFromAssembly(t.Assembly);

            genericArguments = new List <TypeDescriptor>();
            if (UnderlyingType.IsGenericType)
            {
                GenericFullName = UnderlyingType.GetGenericTypeDefinition().FullName;
                GenericAssemblyQualifiedName = UnderlyingType.GetGenericTypeDefinition().AssemblyQualifiedName;
                foreach (var genericArgument in UnderlyingType.GetGenericArguments())
                {
                    genericArguments.Add(TypeDescriptor.CreateFromType(genericArgument));
                }
            }
            else
            {
                GenericAssemblyQualifiedName = UnderlyingType.AssemblyQualifiedName;
                GenericFullName = UnderlyingType.FullName;
            }

            if (t.BaseType != null)
            {
                System.IO.File.AppendAllText("/tmp/log", string.Format("Setting base type '{0}' for '{1}' in Init method\n", t.BaseType.FullName, t.FullName));
                baseType = TypeDescriptor.CreateFromType(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;
        }
Beispiel #5
0
        private void Init(Type t)
        {
            UnderlyingType = t;

            TypeAssembly = AssemblyDescriptor.CreateFromAssembly(t.Assembly);

            genericArguments = new List <TypeDescriptor>();
            if (UnderlyingType.IsGenericType)
            {
                GenericFullName = UnderlyingType.GetGenericTypeDefinition().FullName;
                GenericAssemblyQualifiedName = UnderlyingType.GetGenericTypeDefinition().AssemblyQualifiedName;
                foreach (var genericArgument in UnderlyingType.GetGenericArguments())
                {
                    genericArguments.Add(TypeDescriptor.CreateFromType(genericArgument));
                }
            }
            else
            {
                GenericAssemblyQualifiedName = UnderlyingType.AssemblyQualifiedName;
                GenericFullName = UnderlyingType.FullName;
            }

            if (t.BaseType != null)
            {
                baseType = TypeDescriptor.CreateFromType(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;
        }
Beispiel #6
0
        private Action <PrimitiveWriter, object> PrepareWriteMethod(Type actualType, int surrogateId)
        {
            var typeId = -1;

            if (surrogateId == -1)
            {
                typeId = typeIndices[TypeDescriptor.CreateFromType(actualType)];
                var specialWrite = LinkSpecialWrite(actualType, typeId);
                if (specialWrite != null)
                {
                    // linked methods are not added to writeMethodCache, there's no point
                    return(specialWrite);
                }
            }

            if (!isGenerating)
            {
                if (surrogateId != -1)
                {
                    return((pw, o) => InvokeCallbacksAndWriteObject(surrogatesForObjects.GetByIndex(surrogateId).DynamicInvoke(new [] { o })));
                }
                return((pw, o) => WriteObjectUsingReflection(pw, o, typeId));
            }

            var method = new WriteMethodGenerator(actualType, treatCollectionAsUserObject, surrogateId,
                                                  Helpers.GetFieldInfo <ObjectWriter, Dictionary <TypeDescriptor, int> >(x => x.typeIndices),
                                                  Helpers.GetFieldInfo <ObjectWriter, InheritanceAwareList <Delegate> >(x => x.surrogatesForObjects),
                                                  Helpers.GetFieldInfo <ObjectWriter, bool>(x => x.typeIdJustWritten),
                                                  Helpers.GetMethodInfo <ObjectWriter>(x => x.InvokeCallbacksAndWriteObject(null))).Method;
            var result = (Action <PrimitiveWriter, object>)method.CreateDelegate(typeof(Action <PrimitiveWriter, object>), this);

            if (writeMethodCache != null)
            {
                writeMethodCache.Add(actualType, method);
            }
            return(result);
        }
Beispiel #7
0
        private List <FieldInfoOrEntryToOmit> VerifyStructure(VersionToleranceLevel versionToleranceLevel)
        {
            if (TypeAssembly.ModuleGUID == UnderlyingType.Module.ModuleVersionId)
            {
                return(StampHelpers.GetFieldsInSerializationOrder(UnderlyingType, true).Select(x => new FieldInfoOrEntryToOmit(x)).ToList());
            }

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

            var result = new List <FieldInfoOrEntryToOmit>();

            var assemblyTypeDescriptor = TypeDescriptor.CreateFromType(UnderlyingType);

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

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

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

            if (cmpResult.FieldsChanged.Any())
            {
                throw new InvalidOperationException(string.Format("Field {0} type changed.", cmpResult.FieldsChanged[0].Name));
            }

            if (cmpResult.FieldsAdded.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowFieldAddition))
            {
                throw new InvalidOperationException(string.Format("Field added: {0}.", cmpResult.FieldsAdded[0].Name));
            }
            if (cmpResult.FieldsRemoved.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.AllowFieldRemoval))
            {
                throw new InvalidOperationException(string.Format("Field removed: {0}.", cmpResult.FieldsRemoved[0].Name));
            }

            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);
        }