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)); }