예제 #1
0
        /// <summary>
        /// Filter the fields info to preserve only the fields that are marked by MarshalOrder,
        /// and sort the filtered fields.
        /// </summary>
        /// <param name="declaredFieldsInfo">Fields to be filtered and sorted.</param>
        /// <returns>Filtered and sorted fields info.</returns>
        protected static FieldInfo[] FilterAndSortFields(FieldInfo[] declaredFieldsInfo)
        {
            List <FieldInfo> fieldsList      = declaredFieldsInfo.ToList();
            List <int>       toRemoveIndices = new List <int>();

            for (int i = 0; i < fieldsList.Count; i++)
            {
                object[] fieldAttributes = fieldsList[i].GetCustomAttributes(typeof(MarshalOrderAttribute), true);
                if (fieldAttributes.Length != 1)
                {
                    toRemoveIndices.Add(i);
                    if (fieldAttributes.Length > 1)
                    {
                        // Prohibit the case where there are multiple MarshalOrder attributes.
                        throw new InvalidMarshallableException(string.Format("MarshalOrder marked {0} times.", fieldAttributes.Length));
                    }
                    continue;
                }
            }
            foreach (int index in toRemoveIndices.OrderByDescending(v => v))
            {
                // Fields that have not been marked with MarshalOrder attribute
                // will not be marshalled from or unmarshalled to.
                fieldsList.RemoveAt(index);
            }
            declaredFieldsInfo = fieldsList.ToArray();
            FieldComparer fieldComparer = new FieldComparer();

            Array.Sort(declaredFieldsInfo, (x, y) => { return(fieldComparer.Compare(x, y)); });

            // Make sure there are no duplicate attributes.
            int lastOrder = -1;

            for (int i = 0; i < declaredFieldsInfo.Length; i++)
            {
                MarshalOrderAttribute attribute = (MarshalOrderAttribute)declaredFieldsInfo[i]
                                                  .GetCustomAttributes(typeof(MarshalOrderAttribute), true)[0];
                if (i == 0)
                {
                    lastOrder = attribute.Order;
                }
                else if (attribute.Order == lastOrder)
                {
                    throw new InvalidMarshallableException(string.Format("Field {0} has a conflicting ID {1}.", declaredFieldsInfo[i].Name, lastOrder));
                }
            }
            return(fieldsList.ToArray());
        }
예제 #2
0
        public int Compare(FieldInfo x, FieldInfo y)
        {
            object[] xAttributes = x.GetCustomAttributes(typeof(MarshalOrderAttribute), true);
            object[] yAttributes = y.GetCustomAttributes(typeof(MarshalOrderAttribute), true);
            if (xAttributes.Length < 1)
            {
                throw new ArgumentException(
                          string.Format("The field {0} has {1} MarshalOrderAttribute.", x.Name, xAttributes.Length));
            }
            if (yAttributes.Length < 1)
            {
                throw new ArgumentException(
                          string.Format("The field {0} has {1} MarshalOrderAttribute.", y.Name, yAttributes.Length));
            }
            MarshalOrderAttribute xAttribute = (MarshalOrderAttribute)xAttributes[0];
            MarshalOrderAttribute yAttribute = (MarshalOrderAttribute)yAttributes[0];

            return(xAttribute.Order.CompareTo(yAttribute.Order));
        }