The Labs \ Source Viewer \ SSCLI \ System.Collections.Specialized \ BitVector32

  1. //------------------------------------------------------------------------------
  2. // <copyright file="BitVector32.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Collections.Specialized
  16. {
  17.    
  18.     using System.Diagnostics;
  19.     using System.Text;
  20.     using System;
  21.     using Microsoft.Win32;
  22.    
  23.     /// <devdoc>
  24.     /// <para>Provides a simple light bit vector with easy integer or Boolean access to
  25.     /// a 32 bit storage.</para>
  26.     /// </devdoc>
  27.     public struct BitVector32
  28.     {
  29.         private uint data;
  30.        
  31.         /// <devdoc>
  32.         /// <para>Initializes a new instance of the BitVector32 structure with the specified internal data.</para>
  33.         /// </devdoc>
  34.         public BitVector32(int data)
  35.         {
  36.             this.data = (uint)data;
  37.         }
  38.        
  39.         /// <devdoc>
  40.         /// <para>Initializes a new instance of the BitVector32 structure with the information in the specified
  41.         /// value.</para>
  42.         /// </devdoc>
  43.         public BitVector32(BitVector32 value)
  44.         {
  45.             this.data = value.data;
  46.         }
  47.        
  48.         /// <devdoc>
  49.         /// <para>Gets or sets a value indicating whether all the specified bits are set.</para>
  50.         /// </devdoc>
  51.         public bool this[int bit]
  52.         {
  53.             get { return (data & bit) == (uint)bit; }
  54.             set {
  55.                 if (value) {
  56.                     data |= (uint)bit;
  57.                 }
  58.                 else {
  59.                     data &= ~(uint)bit;
  60.                 }
  61.             }
  62.         }
  63.        
  64.         /// <devdoc>
  65.         /// <para>Gets or sets the value for the specified section.</para>
  66.         /// </devdoc>
  67.         public int this[Section section]
  68.         {
  69.             get { return (int)((data & (uint)(section.Mask << section.Offset)) >> section.Offset); }
  70.             set {
  71.                 #if DEBUG
  72.                 if ((value & section.Mask) != value) {
  73.                     Debug.Fail("Value out of bounds on BitVector32 Section Set!");
  74.                 }
  75.                 #endif
  76.                 value <<= section.Offset;
  77.                 int offsetMask = (65535 & (int)section.Mask) << section.Offset;
  78.                 data = (data & ~(uint)offsetMask) | ((uint)value & (uint)offsetMask);
  79.             }
  80.         }
  81.        
  82.         /// <devdoc>
  83.         /// returns the raw data stored in this bit vector...
  84.         /// </devdoc>
  85.         public int Data {
  86.             get { return (int)data; }
  87.         }
  88.        
  89.         private static short CountBitsSet(short mask)
  90.         {
  91.            
  92.             // yes, I know there are better algorithms, however, we know the
  93.             // bits are always right aligned, with no holes (i.e. always 00000111,
  94.             // never 000100011), so this is just fine...
  95.             //
  96.             short value = 0;
  97.             while ((mask & 1) != 0) {
  98.                 value++;
  99.                 mask >>= 1;
  100.             }
  101.             return value;
  102.         }
  103.        
  104.         /// <devdoc>
  105.         /// <para> Creates the first mask in a series.</para>
  106.         /// </devdoc>
  107.         public static int CreateMask()
  108.         {
  109.             return CreateMask(0);
  110.         }
  111.        
  112.         /// <devdoc>
  113.         /// Creates the next mask in a series.
  114.         /// </devdoc>
  115.         public static int CreateMask(int previous)
  116.         {
  117.             if (previous == 0) {
  118.                 return 1;
  119.             }
  120.            
  121.             if (previous == unchecked((int)2147483648u)) {
  122.                 throw new InvalidOperationException(SR.GetString(SR.BitVectorFull));
  123.             }
  124.            
  125.             return previous << 1;
  126.         }
  127.        
  128.         /// <devdoc>
  129.         /// Given a highValue, creates the mask
  130.         /// </devdoc>
  131.         private static short CreateMaskFromHighValue(short highValue)
  132.         {
  133.             short required = 16;
  134.             while ((highValue & 32768) == 0) {
  135.                 required--;
  136.                 highValue <<= 1;
  137.             }
  138.            
  139.             ushort value = 0;
  140.             while (required > 0) {
  141.                 required--;
  142.                 value <<= 1;
  143.                 value |= 1;
  144.             }
  145.            
  146.             return unchecked((short)value);
  147.         }
  148.        
  149.         /// <devdoc>
  150.         /// <para>Creates the first section in a series, with the specified maximum value.</para>
  151.         /// </devdoc>
  152.         public static Section CreateSection(short maxValue)
  153.         {
  154.             return CreateSectionHelper(maxValue, 0, 0);
  155.         }
  156.        
  157.         /// <devdoc>
  158.         /// <para>Creates the next section in a series, with the specified maximum value.</para>
  159.         /// </devdoc>
  160.         public static Section CreateSection(short maxValue, Section previous)
  161.         {
  162.             return CreateSectionHelper(maxValue, previous.Mask, previous.Offset);
  163.         }
  164.        
  165.         private static Section CreateSectionHelper(short maxValue, short priorMask, short priorOffset)
  166.         {
  167.             if (maxValue < 1) {
  168.                 throw new ArgumentException(SR.GetString(SR.Argument_InvalidValue, "maxValue", 0), "maxValue");
  169.             }
  170.             #if DEBUG
  171.             int maskCheck = CreateMaskFromHighValue(maxValue);
  172.             int offsetCheck = priorOffset + CountBitsSet(priorMask);
  173.             Debug.Assert(maskCheck <= short.MaxValue && offsetCheck < 32, "Overflow on BitVector32");
  174.             #endif
  175.             short offset = (short)(priorOffset + CountBitsSet(priorMask));
  176.             if (offset >= 32) {
  177.                 throw new InvalidOperationException(SR.GetString(SR.BitVectorFull));
  178.             }
  179.             return new Section(CreateMaskFromHighValue(maxValue), offset);
  180.         }
  181.        
  182.         public override bool Equals(object o)
  183.         {
  184.             if (!(o is BitVector32)) {
  185.                 return false;
  186.             }
  187.            
  188.             return data == ((BitVector32)o).data;
  189.         }
  190.        
  191.         public override int GetHashCode()
  192.         {
  193.             return base.GetHashCode();
  194.         }
  195.        
  196.         /// <devdoc>
  197.         /// </devdoc>
  198.         public static string ToString(BitVector32 value)
  199.         {
  200.                 /*"BitVector32{".Length*/                /*32 bits*/                /*"}".Length"*/            StringBuilder sb = new StringBuilder(12 + 32 + 1);
  201.             sb.Append("BitVector32{");
  202.             int locdata = (int)value.data;
  203.             for (int i = 0; i < 32; i++) {
  204.                 if ((locdata & 2147483648u) != 0) {
  205.                     sb.Append("1");
  206.                 }
  207.                 else {
  208.                     sb.Append("0");
  209.                 }
  210.                 locdata <<= 1;
  211.             }
  212.             sb.Append("}");
  213.             return sb.ToString();
  214.         }
  215.        
  216.         /// <devdoc>
  217.         /// </devdoc>
  218.         public override string ToString()
  219.         {
  220.             return BitVector32.ToString(this);
  221.         }
  222.        
  223.         /// <devdoc>
  224.         /// <para>
  225.         /// Represents an section of the vector that can contain a integer number.</para>
  226.         /// </devdoc>
  227.         public struct Section
  228.         {
  229.             private readonly short mask;
  230.             private readonly short offset;
  231.            
  232.             internal Section(short mask, short offset)
  233.             {
  234.                 this.mask = mask;
  235.                 this.offset = offset;
  236.             }
  237.            
  238.             public short Mask {
  239.                 get { return mask; }
  240.             }
  241.            
  242.             public short Offset {
  243.                 get { return offset; }
  244.             }
  245.            
  246.             public override bool Equals(object o)
  247.             {
  248.                 if (o is Section)
  249.                     return Equals((Section)o);
  250.                 else
  251.                     return false;
  252.             }
  253.            
  254.             public bool Equals(Section obj)
  255.             {
  256.                 return obj.mask == mask && obj.offset == offset;
  257.             }
  258.            
  259.             public static bool operator ==(Section a, Section b)
  260.             {
  261.                 return a.Equals(b);
  262.             }
  263.            
  264.             public static bool operator !=(Section a, Section b)
  265.             {
  266.                 return !(a == b);
  267.             }
  268.            
  269.             public override int GetHashCode()
  270.             {
  271.                 return base.GetHashCode();
  272.             }
  273.            
  274.             /// <devdoc>
  275.             /// </devdoc>
  276.             public static string ToString(Section value)
  277.             {
  278.                 return "Section{0x" + Convert.ToString(value.Mask, 16) + ", 0x" + Convert.ToString(value.Offset, 16) + "}";
  279.             }
  280.            
  281.             /// <devdoc>
  282.             /// </devdoc>
  283.             public override string ToString()
  284.             {
  285.                 return Section.ToString(this);
  286.             }
  287.            
  288.         }
  289.     }
  290. }

Developer Fusion