diff --git a/Core/Extensions/BitHelper.cs b/Core/Extensions/BitHelper.cs
index 67f77e2b..d32691f4 100644
--- a/Core/Extensions/BitHelper.cs
+++ b/Core/Extensions/BitHelper.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.InteropServices;
namespace Vanara.Extensions
{
@@ -8,9 +9,22 @@ namespace Vanara.Extensions
/// Gets the bit value at the specified index in a bit vector.
/// The type of the bit vector. Must be of type .
/// The bit vector.
- /// The index of the bit to get.
+ /// The zero-based index of the bit to get.
/// if the bit is set (1); otherwise.
- public static bool GetBit(ref T bits, byte idx) where T : IConvertible => (bits.ToInt64(null) & 1 << idx) != 0;
+ public static bool GetBit(T bits, byte idx) where T : IConvertible => (idx < (Marshal.SizeOf(typeof(T)) * 8)) ? (bits.ToInt64(null) & 1 << idx) != 0 : throw new ArgumentOutOfRangeException(nameof(idx));
+
+ /// Gets the bit array value from the specified range in a bit vector.
+ /// The type of the bit vector. Must be of type .
+ /// The bit vector.
+ /// The zero-based start index of the bit range to get.
+ /// The number of sequential bits to fetch starting at .
+ /// The value of the requested bit range.
+ public static T GetBits(T bits, byte startIdx, byte count) where T : IConvertible
+ {
+ if (startIdx >= (Marshal.SizeOf(typeof(T)) * 8)) throw new ArgumentOutOfRangeException(nameof(startIdx));
+ if (count + startIdx > (Marshal.SizeOf(typeof(T)) * 8)) throw new ArgumentOutOfRangeException(nameof(count));
+ return (T)Convert.ChangeType((bits.ToInt64(null) >> startIdx) & ((1 << count) - 1), typeof(T));
+ }
/// Sets the bit value at the specified index in a bit vector.
/// The type of the bit vector. Must be of type .
@@ -19,9 +33,26 @@ namespace Vanara.Extensions
/// If set to , set the bit (= 1); otherwise, clear the bit (= 0).
public static void SetBit(ref T bits, byte idx, bool value) where T : IConvertible
{
+ if (idx >= (Marshal.SizeOf(typeof(T)) * 8)) throw new ArgumentOutOfRangeException(nameof(idx));
long bit = 1 << idx;
var l = bits.ToInt64(null);
bits = (T)Convert.ChangeType(value ? l | bit : l & ~bit, typeof(T));
}
+
+ /// Sets the bit values at the specified range in a bit vector.
+ /// The type of the bit vector. Must be of type .
+ /// The type of the value. Must be of type .
+ /// The bit vector.
+ /// The zero-based start index of the bit range to set.
+ /// The number of sequential bits to set starting at .
+ /// The value to set within the specified range of .
+ public static void SetBits(ref T bits, byte startIdx, byte count, TValue value) where T : IConvertible where TValue : IConvertible
+ {
+ if (startIdx >= (Marshal.SizeOf(typeof(T)) * 8)) throw new ArgumentOutOfRangeException(nameof(startIdx));
+ if (count + startIdx > (Marshal.SizeOf(typeof(T)) * 8)) throw new ArgumentOutOfRangeException(nameof(count));
+ var val = value.ToInt64(null);
+ if (val >= (1 << count)) throw new ArgumentOutOfRangeException(nameof(value));
+ bits = (T)Convert.ChangeType(bits.ToInt64(null) & ~(((1 << count) - 1) << startIdx) | (val << startIdx), typeof(T));
+ }
}
}
\ No newline at end of file