/// <summary> /// Reads a signed integer with the specified range from an IValueReader. /// </summary> /// <param name="reader">IValueReader to read the value from.</param> /// <param name="name">Name of the value to read.</param> /// <param name="minValue">Minimum (inclusive) value that the read value can be.</param> /// <param name="maxValue">Maximum (inclusive) value that the read value can be.</param> /// <returns>Value read from the IValueReader.</returns> /// <exception cref="ArgumentOutOfRangeException"><c>maxValue</c> is out of range.</exception> public static int ReadUInt(this IValueReader reader, string name, int minValue, int maxValue) { if (maxValue < minValue) { throw new ArgumentOutOfRangeException("maxValue", "MaxValue must be greater than or equal to MinValue."); } // Find the number of bits required for the range of desired values var maxWriteValue = (uint)(maxValue - minValue); var bitsRequired = BitOps.RequiredBits(maxWriteValue); // Read the value, which is the offset from the minimum possible value, then add it to the minimum // possible value var offsetFromMin = reader.ReadUInt(name, bitsRequired); return(minValue + (int)offsetFromMin); }
/// <summary> /// Initializes the <see cref="EnumHelper{T}"/> class. /// </summary> /// <exception cref="MethodAccessException"><typeparamref name="T"/> is not an enum.</exception> static EnumHelper() { var supportedCastTypes = new Type[] { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int) }; // Make sure we have an enum if (!typeof(T).IsEnum) { throw CreateGenericTypeIsNotEnumException(); } // Get the defined enum values _values = Enum.GetValues(typeof(T)).Cast <T>().ToCompact(); // Check if we have an underlying enum type that supports our ToInt/FromInt operations var underlyingType = Enum.GetUnderlyingType(typeof(T)); if (supportedCastTypes.Contains(underlyingType)) { // Create the funcs to cast to/from an int _toInt = CreateToInt(); _fromInt = CreateFromInt(); // Get all the defined values casted to int var valuesAsInt = _values.Select(_toInt); // Find the min and max values _minValue = valuesAsInt.Min(); _maxValue = valuesAsInt.Max(); Debug.Assert(_minValue <= _maxValue); // Find the difference between the min and max so we can cache how many bits are required for the range var diff = _maxValue - _minValue; Debug.Assert(diff >= 0); Debug.Assert(diff >= uint.MinValue); var bitsReq = BitOps.RequiredBits((uint)diff); Debug.Assert(bitsReq > 0); Debug.Assert(bitsReq < byte.MaxValue); _bitsRequired = (byte)bitsReq; } }
/// <summary> /// Writes a signed integer with the specified range to an IValueWriter. /// </summary> /// <param name="writer">IValueWriter to write to.</param> /// <param name="value">Value to write.</param> /// <param name="name">Name of the value to write.</param> /// <param name="minValue">Minimum (inclusive) value that the written value can be.</param> /// <param name="maxValue">Maximum (inclusive) value that the written value can be.</param> /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is greater than <paramref name="maxValue"/> /// or less than <paramref name="minValue"/>.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxValue"/> is less than <paramref name="minValue"/>.</exception> public static void Write(this IValueWriter writer, string name, int value, int minValue, int maxValue) { if (value < minValue || value > maxValue) { throw new ArgumentOutOfRangeException("value", "Value parameter must be between minValue and maxValue."); } if (maxValue < minValue) { throw new ArgumentOutOfRangeException("maxValue", "MaxValue must be greater than or equal to MinValue."); } // Find the number of bits required for the range of desired values var maxWriteValue = (uint)(maxValue - minValue); var bitsRequired = BitOps.RequiredBits(maxWriteValue); // Subtract the minimum value from the value since we want to write how high above the minimum value // the value is, not the actual value var offsetFromMin = (uint)(value - minValue); writer.Write(name, offsetFromMin, bitsRequired); Debug.Assert((value - minValue) <= maxWriteValue); Debug.Assert((1 << bitsRequired) >= maxWriteValue); }