private static IFieldOrderFacet Create(FieldOrderAttribute attribute, IFacetHolder holder) {
     return attribute == null ? null : new FieldOrderFacetAnnotation(attribute.Value, holder);
 }
Ejemplo n.º 2
0
        protected TypeNode(TypeNode parent, MemberInfo memberInfo) : this(parent)
        {
            if (memberInfo == null)
            {
                return;
            }

            Name = memberInfo.Name;

            var propertyInfo = memberInfo as PropertyInfo;
            var fieldInfo    = memberInfo as FieldInfo;

            if (propertyInfo != null)
            {
                _type       = propertyInfo.PropertyType;
                ValueGetter = declaringValue => propertyInfo.GetValue(declaringValue, null);
                ValueSetter = (obj, value) => propertyInfo.SetValue(obj, value, null);
            }
            else if (fieldInfo != null)
            {
                _type       = fieldInfo.FieldType;
                ValueGetter = fieldInfo.GetValue;
                ValueSetter = fieldInfo.SetValue;
            }
            else
            {
                throw new NotSupportedException(string.Format("{0} not supported", memberInfo.GetType().Name));
            }

            _underlyingType = Nullable.GetUnderlyingType(Type);

            object[] attributes = memberInfo.GetCustomAttributes(true);

            IgnoreAttribute = attributes.OfType <IgnoreAttribute>().SingleOrDefault();

            /* Don't go any further if we're ignoring this. */
            if (IgnoreAttribute != null)
            {
                return;
            }

            FieldOrderAttribute fieldOrderAttribute = attributes.OfType <FieldOrderAttribute>().SingleOrDefault();
            if (fieldOrderAttribute != null)
            {
                _order = fieldOrderAttribute.Order;
                if (fieldOrderAttribute.ConverterType != null)
                {
                    var typeConverter       = (IValueConverter)Activator.CreateInstance(fieldOrderAttribute.ConverterType);
                    var originalValueGetter = ValueGetter;
                    var originalValueSetter = ValueSetter;
                    ValueGetter = declaringValue => typeConverter.Convert(originalValueGetter(declaringValue), fieldOrderAttribute.ConverterParameter, null);
                    ValueSetter = (obj, value) => originalValueSetter(obj, typeConverter.ConvertBack(value, fieldOrderAttribute.ConverterParameter, null));
                }
            }


            SerializeAsAttribute serializeAsAttribute = attributes.OfType <SerializeAsAttribute>().SingleOrDefault();
            if (serializeAsAttribute != null)
            {
                _serializedType = serializeAsAttribute.SerializedType;
                Endianness      = serializeAsAttribute.Endianness;

                if (!string.IsNullOrEmpty(serializeAsAttribute.Encoding))
                {
                    Encoding = Encoding.GetEncoding(serializeAsAttribute.Encoding);
                }
            }


            FieldLengthAttribute = attributes.OfType <FieldLengthAttribute>().SingleOrDefault();
            if (FieldLengthAttribute != null)
            {
                FieldLengthBinding = new Binding(FieldLengthAttribute, GetBindingLevel(FieldLengthAttribute.Binding));
            }

            FieldCountAttribute = attributes.OfType <FieldCountAttribute>().SingleOrDefault();
            if (FieldCountAttribute != null)
            {
                FieldCountBinding = new Binding(FieldCountAttribute, FindAncestorLevel(FieldCountAttribute.Binding));
            }

            FieldOffsetAttribute = attributes.OfType <FieldOffsetAttribute>().SingleOrDefault();
            if (FieldOffsetAttribute != null)
            {
                FieldOffsetBinding = new Binding(FieldOffsetAttribute, GetBindingLevel(FieldOffsetAttribute.Binding));
            }

            SerializeWhenAttribute[] serializeWhenAttributes = attributes.OfType <SerializeWhenAttribute>().ToArray();
            SerializeWhenAttributes = new ReadOnlyCollection <SerializeWhenAttribute>(serializeWhenAttributes);

            if (SerializeWhenAttributes.Any())
            {
                SerializeWhenBindings = new ReadOnlyCollection <ConditionalBinding>(
                    serializeWhenAttributes.Select(
                        attribute => new ConditionalBinding(attribute, GetBindingLevel(attribute.Binding))).ToList());
            }

            SubtypeAttribute[] subtypeAttributes = attributes.OfType <SubtypeAttribute>().ToArray();
            SubtypeAttributes = new ReadOnlyCollection <SubtypeAttribute>(subtypeAttributes);

            if (SubtypeAttributes.Count > 0)
            {
                IEnumerable <IGrouping <BindingInfo, SubtypeAttribute> > bindingGroups =
                    SubtypeAttributes.GroupBy(subtypeAttribute => subtypeAttribute.Binding);

                if (bindingGroups.Count() > 1)
                {
                    throw new BindingException("Subtypes must all use the same binding configuration.");
                }

                SubtypeAttribute firstBinding = SubtypeAttributes[0];
                SubtypeBinding = new Binding(firstBinding, GetBindingLevel(firstBinding.Binding));

                var valueGroups = SubtypeAttributes.GroupBy(attribute => attribute.Value);
                if (valueGroups.Count() < SubtypeAttributes.Count)
                {
                    throw new InvalidOperationException("Subtype values must be unique.");
                }

                if (SubtypeBinding.BindingMode == BindingMode.TwoWay)
                {
                    var subTypeGroups = SubtypeAttributes.GroupBy(attribute => attribute.Subtype);
                    if (subTypeGroups.Count() < SubtypeAttributes.Count)
                    {
                        throw new InvalidOperationException("Subtypes must be unique for two-way subtype bindings.  Set BindingMode to OneWay to disable updates to the binding source during serialization.");
                    }
                }
            }


            SerializeUntilAttribute = attributes.OfType <SerializeUntilAttribute>().SingleOrDefault();
            if (SerializeUntilAttribute != null)
            {
                SerializeUntilBinding = new Binding(SerializeUntilAttribute,
                                                    GetBindingLevel(SerializeUntilAttribute.Binding));
            }

            ItemLengthAttribute = attributes.OfType <ItemLengthAttribute>().SingleOrDefault();
            if (ItemLengthAttribute != null)
            {
                ItemLengthBinding = new Binding(ItemLengthAttribute, GetBindingLevel(ItemLengthAttribute.Binding));
            }

            ItemSerializeUntilAttribute = attributes.OfType <ItemSerializeUntilAttribute>().SingleOrDefault();

            if (ItemSerializeUntilAttribute != null)
            {
                ItemSerializeUntilBinding = new Binding(ItemSerializeUntilAttribute,
                                                        GetBindingLevel(ItemSerializeUntilAttribute.Binding));
            }

            BitSizeAttribute = attributes.OfType <BitSizeAttribute>().SingleOrDefault();
        }