You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			225 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------------------------
 | |
| // <copyright file="BitSet.cs" company="Microsoft">
 | |
| //     Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>
 | |
| // <owner current="true" primary="true">Microsoft</owner>
 | |
| //------------------------------------------------------------------------------
 | |
| 
 | |
| namespace System.Xml.Schema {
 | |
| 
 | |
|     using System.Text;
 | |
|     using System.Diagnostics;
 | |
| 
 | |
|     internal sealed class BitSet {
 | |
|         private const int bitSlotShift = 5;
 | |
|         private const int bitSlotMask = (1 << bitSlotShift) - 1;
 | |
| 
 | |
|         private int      count;
 | |
|         private uint[]    bits;
 | |
| 
 | |
|     	private BitSet() {
 | |
|     	}
 | |
| 
 | |
|         public BitSet(int count) {
 | |
|             this.count = count;
 | |
|             bits = new uint[Subscript(count + bitSlotMask)];
 | |
|         }
 | |
| 
 | |
|         public int Count {
 | |
|             get { return count; }
 | |
|         }
 | |
| 
 | |
|         public bool this[int index] {
 | |
|             get {
 | |
|                 return Get(index);
 | |
|             }
 | |
|          }
 | |
| 
 | |
|         public void Clear() {
 | |
|             int bitsLength = bits.Length;
 | |
|             for (int i = bitsLength; i-- > 0 ;) {
 | |
|                 bits[i] = 0;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public void Clear(int index) {
 | |
|             int nBitSlot = Subscript(index);
 | |
|             EnsureLength(nBitSlot + 1);
 | |
|             bits[nBitSlot] &= ~((uint)1 << (index & bitSlotMask));
 | |
|         }
 | |
| 
 | |
|         public void Set(int index) {
 | |
|             int nBitSlot = Subscript(index);
 | |
|             EnsureLength(nBitSlot + 1);
 | |
|             bits[nBitSlot] |= (uint)1 << (index & bitSlotMask);
 | |
|         }
 | |
| 
 | |
| 
 | |
|         public bool Get(int index) {
 | |
|             bool fResult = false;
 | |
|             if (index < count) {
 | |
|                 int nBitSlot = Subscript(index);
 | |
|                 fResult = ((bits[nBitSlot] & (1 << (index & bitSlotMask))) != 0);
 | |
|             }
 | |
|             return fResult;
 | |
|         }
 | |
| 
 | |
|         public int NextSet(int startFrom) {
 | |
|             Debug.Assert(startFrom >= -1 && startFrom <= count);
 | |
|             int offset = startFrom + 1;
 | |
|             if (offset == count) {
 | |
|                 return -1;
 | |
|             }
 | |
|             int nBitSlot = Subscript(offset);
 | |
|             offset &= bitSlotMask;
 | |
|             uint word = bits[nBitSlot] >> offset;
 | |
|             // locate non-empty slot
 | |
|             while (word == 0) {
 | |
|                 if ((++ nBitSlot) == bits.Length ) {
 | |
|                     return -1;
 | |
|                 }
 | |
|                 offset = 0;
 | |
|                 word = bits[nBitSlot];
 | |
|             }
 | |
|             while ((word & (uint)1) == 0) {
 | |
|                 word >>= 1;
 | |
|                 offset ++;
 | |
|             }
 | |
|             return (nBitSlot << bitSlotShift) + offset;
 | |
|         }
 | |
| 
 | |
|         public void And(BitSet other) {
 | |
|             /*
 | |
|              * Need to synchronize  both this and other->
 | |
|              * This might lead to deadlock if one thread grabs them in one order
 | |
|              * while another thread grabs them the other order.
 | |
|              * Use a trick from Doug Lea's book on concurrency,
 | |
|              * somewhat complicated because BitSet overrides hashCode().
 | |
|              */
 | |
|             if (this == other) {
 | |
|                 return;
 | |
|             }
 | |
|             int bitsLength = bits.Length;
 | |
|             int setLength = other.bits.Length;
 | |
|             int n = (bitsLength > setLength) ? setLength : bitsLength;
 | |
|             for (int i = n ; i-- > 0 ;) {
 | |
|                 bits[i] &= other.bits[i];
 | |
|             }
 | |
|             for (; n < bitsLength ; n++) {
 | |
|                 bits[n] = 0;
 | |
|             }
 | |
|         }
 | |
| 
 | |
| 
 | |
|         public void Or(BitSet other) {
 | |
|             if (this == other) {
 | |
|                 return;
 | |
|             }
 | |
|             int setLength = other.bits.Length;
 | |
|             EnsureLength(setLength);
 | |
|             for (int i = setLength; i-- > 0 ;) {
 | |
|                 bits[i] |= other.bits[i];
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public override int GetHashCode() {
 | |
|             int h = 1234;
 | |
|             for (int i = bits.Length; --i >= 0;) {
 | |
|                 h ^= (int)bits[i] * (i + 1);
 | |
|             }
 | |
|             return(int)((h >> 32) ^ h);
 | |
|         }
 | |
| 
 | |
| 
 | |
|         public override bool Equals(object obj) {
 | |
|             // assume the same type
 | |
|             if (obj != null) {
 | |
|                 if (this == obj) {
 | |
|                     return true;
 | |
|                 }
 | |
|                 BitSet other = (BitSet) obj;
 | |
| 
 | |
|                 int bitsLength = bits.Length;
 | |
|                 int setLength = other.bits.Length;
 | |
|                 int n = (bitsLength > setLength) ? setLength : bitsLength;
 | |
|                 for (int i = n ; i-- > 0 ;) {
 | |
|                     if (bits[i] != other.bits[i]) {
 | |
|                         return false;
 | |
|                     }
 | |
|                 }
 | |
|                 if (bitsLength > n) {
 | |
|                     for (int i = bitsLength ; i-- > n ;) {
 | |
|                         if (bits[i] != 0) {
 | |
|                             return false;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     for (int i = setLength ; i-- > n ;) {
 | |
|                         if (other.bits[i] != 0) {
 | |
|                             return false;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 return true;
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         public BitSet Clone() {
 | |
|             BitSet newset = new BitSet();
 | |
|             newset.count = count;
 | |
|             newset.bits = (uint[])bits.Clone();
 | |
|             return newset;
 | |
|         }
 | |
| 
 | |
| 
 | |
|         public bool IsEmpty {
 | |
|             get {
 | |
|                 uint k = 0;
 | |
|                 for (int i = 0; i < bits.Length; i++) {
 | |
|                     k |= bits[i];
 | |
|                 }
 | |
|                 return k == 0;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public bool Intersects(BitSet other) {
 | |
|             int i = Math.Min(this.bits.Length, other.bits.Length);
 | |
|             while (--i >= 0) {
 | |
|                 if ((this.bits[i] & other.bits[i]) != 0) {
 | |
|                     return true;
 | |
|                 }
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         private int Subscript(int bitIndex) {
 | |
|             return bitIndex >> bitSlotShift;
 | |
|         }
 | |
| 
 | |
|         private void EnsureLength(int nRequiredLength) {
 | |
|             /* Doesn't need to be synchronized because it's an internal method. */
 | |
|             if (nRequiredLength > bits.Length) {
 | |
|                 /* Ask for larger of doubled size or required size */
 | |
|                 int request = 2 * bits.Length;
 | |
|                 if (request < nRequiredLength)
 | |
|                     request = nRequiredLength;
 | |
|                 uint[] newBits = new uint[request];
 | |
|                 Array.Copy(bits, newBits, bits.Length);
 | |
|                 bits = newBits;
 | |
|             }
 | |
|         }
 | |
| 
 | |
| #if DEBUG
 | |
|         public void Dump(StringBuilder bb) {
 | |
|             for (int i = 0; i < count; i ++) {
 | |
|                 bb.Append( Get(i) ? "1" : "0");
 | |
|             }
 | |
|         }
 | |
| #endif
 | |
|     };
 | |
| 
 | |
| }
 | |
| 
 |