Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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;
            }
        }
Пример #3
0
        /// <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);
        }