/// <summary> /// Converts the members of the bit field to an integer value. /// </summary> /// <param name="obj">An instance of a struct that implements the interface IBitField.</param> /// <returns>An integer representation of the bit field.</returns> public static ulong ToUInt64(this IBitField obj) { ulong result = 0; // Loop through all the properties foreach (PropertyInfo pi in obj.GetType().GetProperties()) { // Check if the property has an attribute of type BitFieldLengthAttribute BitFieldInfoAttribute bitField = (pi.GetCustomAttribute(typeof(BitFieldInfoAttribute)) as BitFieldInfoAttribute); if (bitField != null) { // Calculate a bitmask using the length of the bit field ulong mask = 0; for (byte i = 0; i < bitField.Length; i++) { mask |= 1UL << i; } // This conversion makes it possible to use different types in the bit field ulong value = Convert.ToUInt64(pi.GetValue(obj)); result |= (value & mask) << bitField.Offset; } } return(result); }
/// <summary> /// Creates a new instance of the provided struct. /// </summary> /// <typeparam name="T">The type of the struct that is to be created.</typeparam> /// <param name="value">The initial value of the struct.</param> /// <returns>The instance of the new struct.</returns> public static T CreateBitField <T>(ulong value) where T : struct { // The created struct has to be boxed, otherwise PropertyInfo.SetValue // will work on a copy instead of the actual object object boxedValue = new T(); // Loop through the properties and set a value to each one foreach (PropertyInfo pi in boxedValue.GetType().GetProperties()) { BitFieldInfoAttribute bitField = (pi.GetCustomAttribute(typeof(BitFieldInfoAttribute)) as BitFieldInfoAttribute); if (bitField != null) { ulong mask = (ulong)Math.Pow(2, bitField.Length) - 1; object setVal = Convert.ChangeType((value >> bitField.Offset) & mask, pi.PropertyType); pi.SetValue(boxedValue, setVal); } } // Unboxing the object return((T)boxedValue); }