Esempio n. 1
0
        protected override VarIntSettings GetSettings(TypeReference fieldType, CustomAttribute attribute)
        {
            VarIntSettings settings = default;

            settings.small  = (ulong)attribute.ConstructorArguments[0].Value;
            settings.medium = (ulong)attribute.ConstructorArguments[1].Value;
            if (attribute.ConstructorArguments.Count == 4)
            {
                settings.large            = (ulong)attribute.ConstructorArguments[2].Value;
                settings.throwIfOverLarge = (bool)attribute.ConstructorArguments[3].Value;
            }
            else
            {
                settings.large = null;
            }


            if (settings.small <= 0)
            {
                throw new VarIntException("Small value should be greater than 0");
            }
            if (settings.medium <= 0)
            {
                throw new VarIntException("Medium value should be greater than 0");
            }
            if (settings.large.HasValue && settings.large.Value <= 0)
            {
                throw new VarIntException("Large value should be greater than 0");
            }

            int smallBits  = BitPackHelper.GetBitCount(settings.small, 64);
            int mediumBits = BitPackHelper.GetBitCount(settings.medium, 64);
            int?largeBits  = settings.large.HasValue ? BitPackHelper.GetBitCount(settings.large.Value, 64) : default(int?);

            if (smallBits >= mediumBits)
            {
                throw new VarIntException("The small bit count should be less than medium bit count");
            }
            if (largeBits.HasValue && mediumBits >= largeBits.Value)
            {
                throw new VarIntException("The medium bit count should be less than large bit count");
            }

            int maxBits = BitPackHelper.GetTypeMaxSize(fieldType, "VarInt");

            if (smallBits > maxBits)
            {
                throw new VarIntException($"Small bit count can not be above target type size, bitCount:{smallBits}, max size:{maxBits}, type:{fieldType.Name}");
            }
            if (mediumBits > maxBits)
            {
                throw new VarIntException($"Medium bit count can not be above target type size, bitCount:{mediumBits}, max size:{maxBits}, type:{fieldType.Name}");
            }
            if (largeBits.HasValue && largeBits.Value > maxBits)
            {
                throw new VarIntException($"Large bit count can not be above target type size, bitCount:{largeBits.Value}, max size:{maxBits}, type:{fieldType.Name}");
            }

            return(settings);
        }
        public static ValueSerializer GetSerializer(ICustomAttributeProvider attributeProvider, TypeReference fieldType)
        {
            CustomAttribute attribute = attributeProvider.GetCustomAttribute <BitCountFromRangeAttribute>();

            int min = (int)attribute.ConstructorArguments[0].Value;
            int max = (int)attribute.ConstructorArguments[1].Value;

            if (min >= max)
            {
                throw new BitCountFromRangeException("Max must be greater than min");
            }

            long minAllowedMin = BitPackHelper.GetTypeMin(fieldType, "BitCountFromRange");
            long maxAllowedMax = BitPackHelper.GetTypeMax(fieldType, "BitCountFromRange");

            if (min < minAllowedMin)
            {
                throw new BitCountFromRangeException($"Min must be less than types min value, min:{min}, min allowed:{minAllowedMin}, type:{fieldType.Name}");
            }

            if (max > maxAllowedMax)
            {
                throw new BitCountFromRangeException($"Max must be greater than types max value, max:{max}, max allowed:{maxAllowedMax}, type:{fieldType.Name}");
            }

            int bitCount = BitPackHelper.GetBitCount(checked ((long)max - min));

            int?minResult;

            if (min == 0)
            {
                minResult = null;
            }
            else
            {
                minResult = min;
            }

            return(new BitCountSerializer(bitCount, BitPackHelper.GetConvertType(fieldType), minResult));
        }