﻿// Decompiled with JetBrains decompiler
// Type: System.Xml.Schema.BitSet
// Assembly: System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 50ABAB51-7DC3-4F0A-A797-0D0C2D124D60
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Xml.dll

using System;
using System.Runtime;

namespace System.Xml.Schema
{
  internal sealed class BitSet
  {
    private int count;
    private uint[] bits;
    private const int bitSlotShift = 5;
    private const int bitSlotMask = 31;

    public int Count
    {
      [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get
      {
        return this.count;
      }
    }

    public bool this[int index]
    {
      [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get
      {
        return this.Get(index);
      }
    }

    public bool IsEmpty
    {
      get
      {
        uint num = 0U;
        for (int index = 0; index < this.bits.Length; ++index)
          num |= this.bits[index];
        return (int) num == 0;
      }
    }

    public BitSet(int count)
    {
      this.count = count;
      this.bits = new uint[this.Subscript(count + 31)];
    }

    private BitSet()
    {
    }

    public void Clear()
    {
      int length = this.bits.Length;
      while (length-- > 0)
        this.bits[length] = 0U;
    }

    public void Clear(int index)
    {
      int index1 = this.Subscript(index);
      this.EnsureLength(index1 + 1);
      this.bits[index1] &= (uint) ~(1 << index);
    }

    public void Set(int index)
    {
      int index1 = this.Subscript(index);
      this.EnsureLength(index1 + 1);
      this.bits[index1] |= (uint) (1 << index);
    }

    public bool Get(int index)
    {
      bool flag = false;
      if (index < this.count)
        flag = ((long) this.bits[this.Subscript(index)] & (long) (1 << index)) != 0L;
      return flag;
    }

    public int NextSet(int startFrom)
    {
      int bitIndex = startFrom + 1;
      if (bitIndex == this.count)
        return -1;
      int index = this.Subscript(bitIndex);
      int num1 = bitIndex & 31;
      uint num2;
      for (num2 = this.bits[index] >> num1; (int) num2 == 0; num2 = this.bits[index])
      {
        if (++index == this.bits.Length)
          return -1;
        num1 = 0;
      }
      while (((int) num2 & 1) == 0)
      {
        num2 >>= 1;
        ++num1;
      }
      return (index << 5) + num1;
    }

    public void And(BitSet other)
    {
      if (this == other)
        return;
      int length1 = this.bits.Length;
      int length2 = other.bits.Length;
      int index1 = length1 > length2 ? length2 : length1;
      int index2 = index1;
      while (index2-- > 0)
        this.bits[index2] &= other.bits[index2];
      for (; index1 < length1; ++index1)
        this.bits[index1] = 0U;
    }

    public void Or(BitSet other)
    {
      if (this == other)
        return;
      int length = other.bits.Length;
      this.EnsureLength(length);
      int index = length;
      while (index-- > 0)
        this.bits[index] |= other.bits[index];
    }

    public override int GetHashCode()
    {
      int num = 1234;
      int length = this.bits.Length;
      while (--length >= 0)
        num ^= (int) this.bits[length] * (length + 1);
      return num ^ num;
    }

    public override bool Equals(object obj)
    {
      if (obj == null)
        return false;
      if (this == obj)
        return true;
      BitSet bitSet = (BitSet) obj;
      int length1 = this.bits.Length;
      int length2 = bitSet.bits.Length;
      int num = length1 > length2 ? length2 : length1;
      int index1 = num;
      while (index1-- > 0)
      {
        if ((int) this.bits[index1] != (int) bitSet.bits[index1])
          return false;
      }
      if (length1 > num)
      {
        int index2 = length1;
        while (index2-- > num)
        {
          if ((int) this.bits[index2] != 0)
            return false;
        }
      }
      else
      {
        int index2 = length2;
        while (index2-- > num)
        {
          if ((int) bitSet.bits[index2] != 0)
            return false;
        }
      }
      return true;
    }

    public BitSet Clone()
    {
      return new BitSet()
      {
        count = this.count,
        bits = (uint[]) this.bits.Clone()
      };
    }

    public bool Intersects(BitSet other)
    {
      int index = Math.Min(this.bits.Length, other.bits.Length);
      while (--index >= 0)
      {
        if (((int) this.bits[index] & (int) other.bits[index]) != 0)
          return true;
      }
      return false;
    }

    private int Subscript(int bitIndex)
    {
      return bitIndex >> 5;
    }

    private void EnsureLength(int nRequiredLength)
    {
      if (nRequiredLength <= this.bits.Length)
        return;
      int length = 2 * this.bits.Length;
      if (length < nRequiredLength)
        length = nRequiredLength;
      uint[] numArray = new uint[length];
      Array.Copy((Array) this.bits, (Array) numArray, this.bits.Length);
      this.bits = numArray;
    }
  }
}
