Beispiel #1
0
        static BitPack()
        {
            var type = typeof(T);

            var options = type.GetCustomAttribute <BitPackOptionsAttribute>();

            Mode        = options?.Mode ?? BitPackMode.NoCompaction;
            s_packBools = Mode != BitPackMode.NoCompaction;

            // get all bit pack properties
            var allProperties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            Array.Sort(allProperties, (a, b) => String.CompareOrdinal(a.Name, b.Name));

            var infos = new List <PackInfo>();
            var bools = new List <PropertyInfo>();

            var offset = 0;

            foreach (var pi in allProperties)
            {
                var attr = pi.GetCustomAttribute <BitPackAttribute>();
                if (attr == null)
                {
                    continue;
                }

                if (pi.PropertyType == typeof(bool))
                {
                    bools.Add(pi);
                    continue;
                }

                int  size;
                Type backing;
                if (pi.PropertyType.IsEnum)
                {
                    backing = Enum.GetUnderlyingType(pi.PropertyType);
                    size    = s_acceptedTypes[backing].Size;
                }
                else
                {
                    if (!s_acceptedTypes.ContainsKey(pi.PropertyType))
                    {
                        throw new Exception(
                                  String.Format("Cannot bit pack {0}.{1} of type {2}. It is not a supported type.", type.FullName, pi.Name, pi.PropertyType.FullName));
                    }

                    size    = s_acceptedTypes[pi.PropertyType].Size;
                    backing = pi.PropertyType;
                }

                infos.Add(new PackInfo {
                    ByteOffset = offset, PropertyInfo = pi, Size = size, BackingType = backing
                });
                offset += size;
            }

            // setup bools
            var bit = 0;

            foreach (var pi in bools)
            {
                infos.Add(new PackInfo {
                    ByteOffset = offset, PropertyInfo = pi, Size = 1, Bit = bit, BackingType = typeof(bool)
                });

                if (!s_packBools)
                {
                    bit = 8;
                }
                else
                {
                    bit++;
                }

                if (bit == 8)
                {
                    offset++;
                    bit = 0;
                }
            }

            if (bit > 0)
            {
                offset++;
            }

            TotalBytes  = offset;
            s_toBytes   = GetToBytesFunc(infos);
            s_fromBytes = GetFromBytesFunc(infos);
        }
Beispiel #2
0
 public BitPackOptionsAttribute(BitPackMode mode)
 {
     Mode = mode;
 }