Пример #1
0
        protected void OnSetupInstance()
        {
            Type type             = GetType();
            Type serializableType = typeof(Serializable);

            // Only do this for user types.
            if (type.Assembly == serializableType.Assembly || !type.IsSubclassOf(serializableType))
            {
                return;
            }

            AttributeMap allAttributes = Context.AllAttributes;

            // And only once per type.
            if (allAttributes.ContainsKey(GetTypeHash()))
            {
                return;
            }

            // Register field attributes of this class
            foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (field.DeclaringType?.Assembly == serializableType.Assembly)
                {
                    continue;
                }

                if (field.IsNotSerialized)
                {
                    continue;
                }

                var attribute = Attribute.GetCustomAttribute(field, typeof(SerializeFieldAttribute)) as SerializeFieldAttribute;
                if (field.IsPrivate && attribute == null)
                {
                    continue;
                }

                Type fieldType = field.FieldType;
                if (fieldType.IsEnum)
                {
                    fieldType = Enum.GetUnderlyingType(fieldType);
                }
                VariantType variantType = Variant.GetVariantType(fieldType);

                // TODO: Support VariantType.VarPtr
                if (variantType == VariantType.VarNone || variantType == VariantType.VarPtr || variantType == VariantType.VarVoidPtr)
                {
                    // Incompatible type.
                    Log.Warning($"Trying to register attribute {field.DeclaringType?.FullName}.{field.Name} which has incompatible type {field.FieldType.Name}.");
                    continue;
                }

                StringList enumNames = _emptyStringList;
                if (field.FieldType.IsEnum)
                {
                    enumNames = new StringList();
                    foreach (string name in field.FieldType.GetEnumNames())
                    {
                        enumNames.Add(name);
                    }
                }

                var accessor     = new VariantFieldAccessor(field, variantType);
                var defaultValue = new Variant();
                try
                {
                    accessor.Get(this, defaultValue);
                }
                catch (ArgumentNullException)
                {
                    defaultValue = new Variant(variantType);
                }
                string attributeName = attribute?.Name ?? field.Name;
                var    info          = new AttributeInfo(accessor.VariantType, attributeName, accessor, enumNames, defaultValue,
                                                         attribute?.Mode ?? AttributeMode.AmDefault);
                Context.RegisterAttribute(GetTypeHash(), info);
            }

            // Register property attributes of this class
            foreach (PropertyInfo property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (property.DeclaringType?.Assembly == serializableType.Assembly)
                {
                    continue;
                }

                // Private (even if partially) properties are not serialized by default.
                var attribute = Attribute.GetCustomAttribute(property, typeof(SerializeFieldAttribute)) as SerializeFieldAttribute;
                if ((property.GetMethod.IsPrivate || property.SetMethod.IsPrivate) && attribute == null)
                {
                    continue;
                }

                if (!property.CanRead || !property.CanWrite)
                {
                    Log.Warning($"Trying to register attribute {property.DeclaringType?.FullName}.{property.Name} which is not readable and writable.");
                    continue;
                }

                Type propertyType = property.PropertyType;
                if (propertyType.IsEnum)
                {
                    propertyType = Enum.GetUnderlyingType(propertyType);
                }
                VariantType variantType = Variant.GetVariantType(propertyType);

                // TODO: Support VariantType.VarPtr
                if (variantType == VariantType.VarNone || variantType == VariantType.VarPtr || variantType == VariantType.VarVoidPtr)
                {
                    // Incompatible type.
                    Log.Warning($"Trying to register attribute {property.DeclaringType?.FullName}.{property.Name} which has incompatible type {property.PropertyType.Name}.");
                    continue;
                }

                StringList enumNames = _emptyStringList;
                if (property.PropertyType.IsEnum)
                {
                    enumNames = new StringList();
                    foreach (string name in property.PropertyType.GetEnumNames())
                    {
                        enumNames.Add(name);
                    }
                }

                var accessor     = new VariantPropertyAccessor(property, variantType);
                var defaultValue = new Variant();
                try
                {
                    accessor.Get(this, defaultValue);
                }
                catch (ArgumentNullException)
                {
                    defaultValue = new Variant(variantType);
                }

                string attributeName = attribute?.Name ?? property.Name;
                var    info          = new AttributeInfo(accessor.VariantType, attributeName, accessor, enumNames, defaultValue,
                                                         attribute?.Mode ?? AttributeMode.AmDefault);
                Context.RegisterAttribute(GetTypeHash(), info);
            }
        }
Пример #2
0
        protected void OnSetupInstance()
        {
            var type             = GetType();
            var serializableType = typeof(Serializable);

            // Only do this for user types.
            if (type.Assembly == serializableType.Assembly || !type.IsSubclassOf(serializableType))
            {
                return;
            }

            var context       = Context;
            var allAttributes = context.AllAttributes;

            // And only once per type.
            if (allAttributes.ContainsKey(GetTypeHash()))
            {
                return;
            }

            // Register attributes of this class
            foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (field.DeclaringType?.Assembly == serializableType.Assembly)
                {
                    continue;
                }

                if (field.IsNotSerialized)
                {
                    continue;
                }

                var attribute = Attribute.GetCustomAttribute(field, typeof(SerializeFieldAttribute)) as SerializeFieldAttribute;
                if (field.IsPrivate && attribute == null)
                {
                    continue;
                }

                var fieldType = field.FieldType;
                if (field.FieldType.IsEnum)
                {
                    fieldType = Enum.GetUnderlyingType(fieldType);
                }
                var variantType = Variant.GetVariantType(fieldType);
                if (variantType == VariantType.VarNone)
                {
                    // Incompatible type.
                    continue;
                }

                // TODO: This needs more work. Serializable should automatically serialize instances of Serializable.
                if (variantType == VariantType.VarPtr)
                {
                    continue;
                }

                // No way to serialize that in any meaningful way.
                if (variantType == VariantType.VarVoidPtr)
                {
                    continue;
                }

                var enumNames = _emptyStringList;
                if (field.FieldType.IsEnum)
                {
                    enumNames = new StringList();
                    foreach (var name in field.FieldType.GetEnumNames())
                    {
                        enumNames.Add(name);
                    }
                }

                var accessor     = new VariantFieldAccessor(field, variantType);
                var defaultValue = new Variant();
                accessor.Get(this, defaultValue);

                var attributeName = attribute?.Name ?? field.Name;
                var info          = new AttributeInfo(accessor.VariantType, attributeName, accessor, enumNames, defaultValue,
                                                      attribute?.Mode ?? AttributeMode.AmDefault);
                context.RegisterAttribute(GetTypeHash(), info);
            }
        }