aboutsummaryrefslogtreecommitdiff
path: root/BDInfo/BitVector32.cs
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-10-26 15:29:56 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-10-26 15:29:56 -0400
commit3d7f75eea3465a34b443cf90d0affe5a637faf5d (patch)
tree47be26c509373d62c560f65b2721c3185ba0e78d /BDInfo/BitVector32.cs
parent0189f4c49dc89654e6aa10c5dd0fc50a0984bfec (diff)
more steps to make provider project portable
Diffstat (limited to 'BDInfo/BitVector32.cs')
-rw-r--r--BDInfo/BitVector32.cs314
1 files changed, 314 insertions, 0 deletions
diff --git a/BDInfo/BitVector32.cs b/BDInfo/BitVector32.cs
new file mode 100644
index 000000000..46f15034b
--- /dev/null
+++ b/BDInfo/BitVector32.cs
@@ -0,0 +1,314 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BDInfo
+{
+ using System.Diagnostics;
+ using System.Text;
+ using System;
+ using Microsoft.Win32;
+
+ /// <devdoc>
+ /// <para>Provides a simple light bit vector with easy integer or Boolean access to
+ /// a 32 bit storage.</para>
+ /// </devdoc>
+ public struct BitVector32
+ {
+ private uint data;
+
+ /// <devdoc>
+ /// <para>Initializes a new instance of the BitVector32 structure with the specified internal data.</para>
+ /// </devdoc>
+ public BitVector32(int data)
+ {
+ this.data = (uint)data;
+ }
+
+ /// <devdoc>
+ /// <para>Initializes a new instance of the BitVector32 structure with the information in the specified
+ /// value.</para>
+ /// </devdoc>
+ public BitVector32(BitVector32 value)
+ {
+ this.data = value.data;
+ }
+
+ /// <devdoc>
+ /// <para>Gets or sets a value indicating whether all the specified bits are set.</para>
+ /// </devdoc>
+ public bool this[int bit]
+ {
+ get
+ {
+ return (data & bit) == (uint)bit;
+ }
+ set
+ {
+ if (value)
+ {
+ data |= (uint)bit;
+ }
+ else
+ {
+ data &= ~(uint)bit;
+ }
+ }
+ }
+
+ /// <devdoc>
+ /// <para>Gets or sets the value for the specified section.</para>
+ /// </devdoc>
+ public int this[Section section]
+ {
+ get
+ {
+ return (int)((data & (uint)(section.Mask << section.Offset)) >> section.Offset);
+ }
+ set
+ {
+#if DEBUG
+ if ((value & section.Mask) != value) {
+ Debug.Fail("Value out of bounds on BitVector32 Section Set!");
+ }
+#endif
+ value <<= section.Offset;
+ int offsetMask = (0xFFFF & (int)section.Mask) << section.Offset;
+ data = (data & ~(uint)offsetMask) | ((uint)value & (uint)offsetMask);
+ }
+ }
+
+ /// <devdoc>
+ /// returns the raw data stored in this bit vector...
+ /// </devdoc>
+ public int Data
+ {
+ get
+ {
+ return (int)data;
+ }
+ }
+
+ private static short CountBitsSet(short mask)
+ {
+
+ // yes, I know there are better algorithms, however, we know the
+ // bits are always right aligned, with no holes (i.e. always 00000111,
+ // never 000100011), so this is just fine...
+ //
+ short value = 0;
+ while ((mask & 0x1) != 0)
+ {
+ value++;
+ mask >>= 1;
+ }
+ return value;
+ }
+
+ /// <devdoc>
+ /// <para> Creates the first mask in a series.</para>
+ /// </devdoc>
+ public static int CreateMask()
+ {
+ return CreateMask(0);
+ }
+
+ /// <devdoc>
+ /// Creates the next mask in a series.
+ /// </devdoc>
+ public static int CreateMask(int previous)
+ {
+ if (previous == 0)
+ {
+ return 1;
+ }
+
+ if (previous == unchecked((int)0x80000000))
+ {
+ throw new InvalidOperationException("Bit vector full");
+ }
+
+ return previous << 1;
+ }
+
+ /// <devdoc>
+ /// Given a highValue, creates the mask
+ /// </devdoc>
+ private static short CreateMaskFromHighValue(short highValue)
+ {
+ short required = 16;
+ while ((highValue & 0x8000) == 0)
+ {
+ required--;
+ highValue <<= 1;
+ }
+
+ ushort value = 0;
+ while (required > 0)
+ {
+ required--;
+ value <<= 1;
+ value |= 0x1;
+ }
+
+ return unchecked((short)value);
+ }
+
+ /// <devdoc>
+ /// <para>Creates the first section in a series, with the specified maximum value.</para>
+ /// </devdoc>
+ public static Section CreateSection(short maxValue)
+ {
+ return CreateSectionHelper(maxValue, 0, 0);
+ }
+
+ /// <devdoc>
+ /// <para>Creates the next section in a series, with the specified maximum value.</para>
+ /// </devdoc>
+ public static Section CreateSection(short maxValue, Section previous)
+ {
+ return CreateSectionHelper(maxValue, previous.Mask, previous.Offset);
+ }
+
+ private static Section CreateSectionHelper(short maxValue, short priorMask, short priorOffset)
+ {
+ if (maxValue < 1)
+ {
+ throw new ArgumentOutOfRangeException("maxValue");
+ }
+#if DEBUG
+ int maskCheck = CreateMaskFromHighValue(maxValue);
+ int offsetCheck = priorOffset + CountBitsSet(priorMask);
+ Debug.Assert(maskCheck <= short.MaxValue && offsetCheck < 32, "Overflow on BitVector32");
+#endif
+ short offset = (short)(priorOffset + CountBitsSet(priorMask));
+ if (offset >= 32)
+ {
+ throw new InvalidOperationException("Bit vector full");
+ }
+ return new Section(CreateMaskFromHighValue(maxValue), offset);
+ }
+
+ public override bool Equals(object o)
+ {
+ if (!(o is BitVector32))
+ {
+ return false;
+ }
+
+ return data == ((BitVector32)o).data;
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ /// <devdoc>
+ /// </devdoc>
+ public static string ToString(BitVector32 value)
+ {
+ StringBuilder sb = new StringBuilder(/*"BitVector32{".Length*/12 + /*32 bits*/32 + /*"}".Length"*/1);
+ sb.Append("BitVector32{");
+ int locdata = (int)value.data;
+ for (int i = 0; i < 32; i++)
+ {
+ if ((locdata & 0x80000000) != 0)
+ {
+ sb.Append("1");
+ }
+ else
+ {
+ sb.Append("0");
+ }
+ locdata <<= 1;
+ }
+ sb.Append("}");
+ return sb.ToString();
+ }
+
+ /// <devdoc>
+ /// </devdoc>
+ public override string ToString()
+ {
+ return BitVector32.ToString(this);
+ }
+
+ /// <devdoc>
+ /// <para>
+ /// Represents an section of the vector that can contain a integer number.</para>
+ /// </devdoc>
+ public struct Section
+ {
+ private readonly short mask;
+ private readonly short offset;
+
+ internal Section(short mask, short offset)
+ {
+ this.mask = mask;
+ this.offset = offset;
+ }
+
+ public short Mask
+ {
+ get
+ {
+ return mask;
+ }
+ }
+
+ public short Offset
+ {
+ get
+ {
+ return offset;
+ }
+ }
+
+ public override bool Equals(object o)
+ {
+ if (o is Section)
+ return Equals((Section)o);
+ else
+ return false;
+ }
+
+ public bool Equals(Section obj)
+ {
+ return obj.mask == mask && obj.offset == offset;
+ }
+
+ public static bool operator ==(Section a, Section b)
+ {
+ return a.Equals(b);
+ }
+
+ public static bool operator !=(Section a, Section b)
+ {
+ return !(a == b);
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ /// <devdoc>
+ /// </devdoc>
+ public static string ToString(Section value)
+ {
+ return "Section{0x" + Convert.ToString(value.Mask, 16) + ", 0x" + Convert.ToString(value.Offset, 16) + "}";
+ }
+
+ /// <devdoc>
+ /// </devdoc>
+ public override string ToString()
+ {
+ return Section.ToString(this);
+ }
+
+ }
+ }
+}